bfd/
authorH.J. Lu <hjl.tools@gmail.com>
Tue, 3 May 2005 01:05:03 +0000 (01:05 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Tue, 3 May 2005 01:05:03 +0000 (01:05 +0000)
2005-05-02  H.J. Lu  <hongjiu.lu@intel.com>

* bfd.c (bfd): Remove section_tail and add section_last.
(bfd_preserve): Likewise.
(bfd_preserve_save): Likewise.
(bfd_preserve_restore): Likewise.
* opncls.c (_bfd_new_bfd): Likewise.

* coffcode.h (coff_compute_section_file_positions): Updated.
(coff_compute_section_file_positions): Likewise.
* elf.c (assign_section_numbers): Likewise.
* elf32-i370.c (i370_elf_size_dynamic_sections): Likewise.
* elf64-mmix.c (mmix_elf_final_link): Likewise.
* elfxx-ia64.c (elfNN_ia64_object_p): Likewise.
* elfxx-mips.c (_bfd_mips_elf_link_hash_table_create): Likewise.
* sunos.c (sunos_add_dynamic_symbols): Likewise.
* xcofflink.c (_bfd_xcoff_bfd_final_link): Likewise.

* ecoff.c (bfd_debug_section): Initialize prev.

* section.c (bfd_section): Add prev.
(bfd_section_list_remove): Updated.
(bfd_section_list_append): New.
(bfd_section_list_insert_after): New.
(bfd_section_list_insert_before): New.
(bfd_section_list_insert): Removed.
(bfd_section_removed_from_list): Updated.
(STD_SECTION): Initialize prev.
(bfd_section_init): Updated.
(bfd_section_list_clear): Updated.

* bfd-in2.h: Regenerated.

gas/

2005-05-02  H.J. Lu  <hongjiu.lu@intel.com>

* write.c (write_object_file): Use bfd_section_double_list_remove
to remove sections.

ld/

2005-05-02  H.J. Lu  <hongjiu.lu@intel.com>

* emultempl/elf32.em (gld${EMULATION_NAME}_strip_empty_section):
Updated for bfd_section_list_remove change.
* ldlang.c (lang_insert_orphan): Likewise.
(strip_excluded_output_sections): Likewise.
(sort_sections_by_lma): New.
(lang_check_section_addresses): Sort the sections before
checking addresses.

19 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
bfd/bfd.c
bfd/coffcode.h
bfd/ecoff.c
bfd/elf.c
bfd/elf32-i370.c
bfd/elf64-mmix.c
bfd/elfxx-ia64.c
bfd/elfxx-mips.c
bfd/opncls.c
bfd/section.c
bfd/sunos.c
bfd/xcofflink.c
gas/ChangeLog
gas/write.c
ld/ChangeLog
ld/emultempl/elf32.em
ld/ldlang.c

index f4c8450d56f6ad3ed4ef4fc86caf28399110e490..e99fd75da0adfc81babcc9f56bc2a88767fb015d 100644 (file)
@@ -1,3 +1,36 @@
+2005-05-02  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * bfd.c (bfd): Remove section_tail and add section_last.
+       (bfd_preserve): Likewise.
+       (bfd_preserve_save): Likewise.
+       (bfd_preserve_restore): Likewise.
+       * opncls.c (_bfd_new_bfd): Likewise.
+
+       * coffcode.h (coff_compute_section_file_positions): Updated.
+       (coff_compute_section_file_positions): Likewise.
+       * elf.c (assign_section_numbers): Likewise.
+       * elf32-i370.c (i370_elf_size_dynamic_sections): Likewise.
+       * elf64-mmix.c (mmix_elf_final_link): Likewise.
+       * elfxx-ia64.c (elfNN_ia64_object_p): Likewise.
+       * elfxx-mips.c (_bfd_mips_elf_link_hash_table_create): Likewise.
+       * sunos.c (sunos_add_dynamic_symbols): Likewise.
+       * xcofflink.c (_bfd_xcoff_bfd_final_link): Likewise.
+
+       * ecoff.c (bfd_debug_section): Initialize prev.
+
+       * section.c (bfd_section): Add prev.
+       (bfd_section_list_remove): Updated.
+       (bfd_section_list_append): New.
+       (bfd_section_list_insert_after): New.
+       (bfd_section_list_insert_before): New.
+       (bfd_section_list_insert): Removed.
+       (bfd_section_removed_from_list): Updated.
+       (STD_SECTION): Initialize prev.
+       (bfd_section_init): Updated.
+       (bfd_section_list_clear): Updated.
+
+       * bfd-in2.h: Regenerated.
+
 2005-05-02  H.J. Lu  <hongjiu.lu@intel.com>
 
        * elf.c (_bfd_elf_new_section_hook): Don't call
index 1e373f28fc2ea9bdae81da96234517d01a0a91c8..64a153fc339f46c71b6de3040e6dd1a88082b704 100644 (file)
@@ -1063,6 +1063,9 @@ typedef struct bfd_section
   /* The next section in the list belonging to the BFD, or NULL.  */
   struct bfd_section *next;
 
+  /* The previous section in the list belonging to the BFD, or NULL.  */
+  struct bfd_section *prev;
+
   /* The field flags contains attributes of the section. Some
      flags are read in from the object file, and some are
      synthesized from other information.  */
@@ -1437,31 +1440,87 @@ extern const struct bfd_symbol * const bfd_ind_symbol;
 /* Macros to handle insertion and deletion of a bfd's sections.  These
    only handle the list pointers, ie. do not adjust section_count,
    target_index etc.  */
+#define bfd_section_double_list_remove(ABFD, S) \
+  do                                                   \
+    {                                                  \
+      asection *_s = S;                                \
+      asection *_next = _s->next;                      \
+      asection *_prev = _s->prev;                      \
+      if (_prev)                                       \
+        _prev->next = _next;                           \
+      else                                             \
+        (ABFD)->sections = _next;                      \
+      if (_next)                                       \
+        {                                              \
+          _next->prev = _prev;                         \
+          _s->next = NULL;                             \
+        }                                              \
+      else                                             \
+        (ABFD)->section_last = _prev;                  \
+    }                                                  \
+  while (0)
 #define bfd_section_list_remove(ABFD, PS) \
+  bfd_section_double_list_remove ((ABFD), *(PS))
+#define bfd_section_double_list_append(ABFD, S) \
+  do                                                   \
+    {                                                  \
+      asection *_s = S;                                \
+      bfd *_abfd = ABFD;                               \
+      _s->next = NULL;                                 \
+      if (_abfd->section_last)                         \
+        {                                              \
+          _s->prev = _abfd->section_last;              \
+          _abfd->section_last->next = _s;              \
+        }                                              \
+      else                                             \
+        _abfd->sections = _s;                          \
+      _abfd->section_last = _s;                        \
+    }                                                  \
+  while (0)
+#define bfd_section_double_list_insert_after(ABFD, A, S) \
   do                                                   \
     {                                                  \
-      asection **_ps = PS;                             \
-      asection *_s = *_ps;                             \
-      *_ps = _s->next;                                 \
-      if (_s->next == NULL)                            \
-        (ABFD)->section_tail = _ps;                    \
+      asection *_a = A;                                \
+      asection *_s = S;                                \
+      if (_a)                                          \
+        {                                              \
+          asection *_next = _a->next;                  \
+          _s->next = _next;                            \
+          _s->prev = _a;                               \
+          _a->next = _s;                               \
+          if (_next)                                   \
+            _s->next->prev = _s;                       \
+          else                                         \
+            (ABFD)->section_last = _s;                 \
+        }                                              \
       else                                             \
-        _s->next = NULL;                               \
+        bfd_section_double_list_append ((ABFD), (S));  \
     }                                                  \
   while (0)
-#define bfd_section_list_insert(ABFD, PS, S) \
+#define bfd_section_double_list_insert_before(ABFD, B, S) \
   do                                                   \
     {                                                  \
-      asection **_ps = PS;                             \
+      asection *_b = B;                                \
       asection *_s = S;                                \
-      _s->next = *_ps;                                 \
-      *_ps = _s;                                       \
-      if (_s->next == NULL)                            \
-        (ABFD)->section_tail = &_s->next;              \
+      if (_b)                                          \
+        {                                              \
+          asection *_prev = _b->prev;                  \
+          _s->prev = _prev;                            \
+          _s->next = _b;                               \
+          _b->prev = _s;                               \
+          if (_prev)                                   \
+            _prev->next = _s;                          \
+          else                                         \
+            (ABFD)->sections = _s;                     \
+        }                                              \
+      else                                             \
+        bfd_section_double_list_append ((ABFD), (S));  \
     }                                                  \
   while (0)
+#define bfd_section_list_insert(ABFD, PS, S) \
+  bfd_section_double_list_insert_before ((ABFD), *(PS), (S))
 #define bfd_section_removed_from_list(ABFD, S) \
-  ((S)->next == NULL && &(S)->next != (ABFD)->section_tail)
+  ((S)->next == NULL && (S) != (ABFD)->section_last)
 
 void bfd_section_list_clear (bfd *);
 
@@ -4026,8 +4085,8 @@ struct bfd
   /* Pointer to linked list of sections.  */
   struct bfd_section *sections;
 
-  /* The place where we add to the section list.  */
-  struct bfd_section **section_tail;
+  /* The last section on the section list.  */
+  struct bfd_section *section_last;
 
   /* The number of sections.  */
   unsigned int section_count;
@@ -4287,7 +4346,7 @@ struct bfd_preserve
   flagword flags;
   const struct bfd_arch_info *arch_info;
   struct bfd_section *sections;
-  struct bfd_section **section_tail;
+  struct bfd_section *section_last;
   unsigned int section_count;
   struct bfd_hash_table section_htab;
 };
index aacc5007be9436690c65410e561a88570f193008..7df66741daca9016b4047dd00ac446e22687496b 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -111,8 +111,8 @@ CODE_FRAGMENT
 .  {* Pointer to linked list of sections.  *}
 .  struct bfd_section *sections;
 .
-.  {* The place where we add to the section list.  *}
-.  struct bfd_section **section_tail;
+.  {* The last section on the section list.  *}
+.  struct bfd_section *section_last;
 .
 .  {* The number of sections.  *}
 .  unsigned int section_count;
@@ -1390,7 +1390,7 @@ CODE_FRAGMENT
 .  flagword flags;
 .  const struct bfd_arch_info *arch_info;
 .  struct bfd_section *sections;
-.  struct bfd_section **section_tail;
+.  struct bfd_section *section_last;
 .  unsigned int section_count;
 .  struct bfd_hash_table section_htab;
 .};
@@ -1424,7 +1424,7 @@ bfd_preserve_save (bfd *abfd, struct bfd_preserve *preserve)
   preserve->arch_info = abfd->arch_info;
   preserve->flags = abfd->flags;
   preserve->sections = abfd->sections;
-  preserve->section_tail = abfd->section_tail;
+  preserve->section_last = abfd->section_last;
   preserve->section_count = abfd->section_count;
   preserve->section_htab = abfd->section_htab;
 
@@ -1435,7 +1435,7 @@ bfd_preserve_save (bfd *abfd, struct bfd_preserve *preserve)
   abfd->arch_info = &bfd_default_arch_struct;
   abfd->flags &= BFD_IN_MEMORY;
   abfd->sections = NULL;
-  abfd->section_tail = &abfd->sections;
+  abfd->section_last = NULL;
   abfd->section_count = 0;
 
   return TRUE;
@@ -1465,7 +1465,7 @@ bfd_preserve_restore (bfd *abfd, struct bfd_preserve *preserve)
   abfd->flags = preserve->flags;
   abfd->section_htab = preserve->section_htab;
   abfd->sections = preserve->sections;
-  abfd->section_tail = preserve->section_tail;
+  abfd->section_last = preserve->section_last;
   abfd->section_count = preserve->section_count;
 
   /* bfd_release frees all memory more recently bfd_alloc'd than
index cd4a371f33a35b27ae5df7c897104ed501982125..cec3992146d4e270a301f6437e70581ba1880083 100644 (file)
@@ -1717,7 +1717,6 @@ coff_set_alignment_hook (bfd *abfd, asection *section, void * scnhdr)
 {
   struct internal_scnhdr *hdr = (struct internal_scnhdr *) scnhdr;
   asection *real_sec;
-  asection **ps;
 
   if ((hdr->s_flags & STYP_OVRFLO) == 0)
     return;
@@ -1729,14 +1728,10 @@ coff_set_alignment_hook (bfd *abfd, asection *section, void * scnhdr)
   real_sec->reloc_count = hdr->s_paddr;
   real_sec->lineno_count = hdr->s_vaddr;
 
-  for (ps = &abfd->sections; *ps != NULL; ps = &(*ps)->next)
+  if (!bfd_section_removed_from_list (abfd, section))
     {
-      if (*ps == section)
-       {
-         bfd_section_list_remove (abfd, ps);
-         --abfd->section_count;
-         break;
-       }
+      bfd_section_list_remove (abfd, section);
+      --abfd->section_count;
     }
 }
 
@@ -3033,11 +3028,12 @@ coff_compute_section_file_positions (bfd * abfd)
     /* Rethread the linked list into sorted order; at the same time,
        assign target_index values.  */
     target_index = 1;
-    abfd->sections = section_list[0];
+    abfd->sections = NULL;
+    abfd->section_last = NULL;
     for (i = 0; i < count; i++)
       {
        current = section_list[i];
-       current->next = section_list[i + 1];
+       bfd_section_list_append (abfd, current);
 
        /* Later, if the section has zero size, we'll be throwing it
           away, so we don't want to number it now.  Note that having
@@ -3056,7 +3052,6 @@ coff_compute_section_file_positions (bfd * abfd)
        else
          current->target_index = target_index++;
       }
-    abfd->section_tail = &current->next;
 
     free (section_list);
   }
index 4ece3c17a21e01014ae67c6321bf2c0dcd590f81..f84f5eaf13612bc7624cc3789cffe4795277ae87 100644 (file)
@@ -52,8 +52,8 @@
 /* This stuff is somewhat copied from coffcode.h.  */
 static asection bfd_debug_section =
 {
-  /* name,      id,  index, next, flags, user_set_vma,             */
-     "*DEBUG*", 0,   0,     NULL, 0,     0,
+  /* name,      id,  index, next, prev, flags, user_set_vma,       */
+     "*DEBUG*", 0,   0,     NULL, NULL, 0,     0,
   /* linker_mark, linker_has_input, gc_mark, segment_mark,         */
      0,           0,                0,       0,
   /* sec_info_type, use_rela_p, has_tls_reloc, has_gp_reloc,       */
index 2af5a8964b6ed96404ca0bee4ca29aa4bafab036..fac05e0d886f14e3cf12be00f9fc9e3eac4e01b7 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -2762,22 +2762,21 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
   /* SHT_GROUP sections are in relocatable files only.  */
   if (link_info == NULL || link_info->relocatable)
     {
-      asection **secp;
+      asection *n;
 
       /* Put SHT_GROUP sections first.  */
-      secp = &abfd->sections;
-      while (*secp)
+      for (sec = abfd->sections; sec; sec = n)
        {
-         d = elf_section_data (*secp);
+         d = elf_section_data (sec);
 
+         n = sec->next;
          if (d->this_hdr.sh_type == SHT_GROUP)
            { 
-             if ((*secp)->flags & SEC_LINKER_CREATED)
+             if (sec->flags & SEC_LINKER_CREATED)
                {
                  /* Remove the linker created SHT_GROUP sections.  */
-                 bfd_section_list_remove (abfd, secp);
+                 bfd_section_list_remove (abfd, sec);
                  abfd->section_count--;
-                 continue;
                }
              else 
                {
@@ -2786,8 +2785,6 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
                  d->this_idx = section_number++;
                }
            }
-
-         secp = &(*secp)->next;
        }
     }
 
index 2166e8aaa7e2d4404cb32a9036735b15fb34432e..3ad7b90f47ba9ed483b7c0eb524a43e29c7fee55 100644 (file)
@@ -756,18 +756,12 @@ i370_elf_size_dynamic_sections (output_bfd, info)
 
       if (strip)
        {
-         asection **spp;
-
-         for (spp = &s->output_section->owner->sections;
-              *spp != NULL;
-              spp = &(*spp)->next)
+         if (!bfd_section_removed_from_list (s->output_section->owner,
+                                             s->output_section))
            {
-             if (*spp == s->output_section)
-               {
-                 bfd_section_list_remove (s->output_section->owner, spp);
-                 --s->output_section->owner->section_count;
-                 break;
-               }
+             bfd_section_list_remove (s->output_section->owner,
+                                      s->output_section);
+             --s->output_section->owner->section_count;
            }
          continue;
        }
index c831d9fbe6432964afd6618b2c4e1333929565ff..a690e7d2dd9ec9253fdef323bcdeee4110caa6c7 100644 (file)
@@ -2249,7 +2249,6 @@ mmix_elf_final_link (abfd, info)
   /* We never output a register section, though we create one for
      temporary measures.  Check that nobody entered contents into it.  */
   asection *reg_section;
-  asection **secpp;
 
   reg_section = bfd_get_section_by_name (abfd, MMIX_REG_SECTION_NAME);
 
@@ -2260,11 +2259,7 @@ mmix_elf_final_link (abfd, info)
        _bfd_abort (__FILE__, __LINE__, _("Register section has contents\n"));
 
       /* Really remove the section.  */
-      for (secpp = &abfd->sections;
-          *secpp != reg_section;
-          secpp = &(*secpp)->next)
-       ;
-      bfd_section_list_remove (abfd, secpp);
+      bfd_section_list_remove (abfd, reg_section);
       --abfd->section_count;
     }
 
index de5793cac51da463c0a34d703a98fb71d3b805dc..a483e2d193c1002a131de477dd7c8b9172e3d262 100644 (file)
@@ -4885,7 +4885,6 @@ static bfd_boolean
 elfNN_ia64_object_p (bfd *abfd)
 {
   asection *sec;
-  asection **tail;
   asection *group, *unwi, *unw;
   flagword flags;
   const char *name;
@@ -4926,8 +4925,6 @@ elfNN_ia64_object_p (bfd *abfd)
          strcpy (stpcpy (unw_name, ".gnu.linkonce.ia64unw."), name);
          unw = bfd_get_section_by_name (abfd, unw_name);
 
-         tail = abfd->section_tail;
-
          /* We need to create a fake group section for it and its
             unwind sections.  */
          group = bfd_make_section_anyway (abfd, name);
@@ -4936,9 +4933,8 @@ elfNN_ia64_object_p (bfd *abfd)
            return FALSE;
 
          /* Move the fake group section to the beginning.  */
-         BFD_ASSERT (*tail == group);
-         bfd_section_list_remove (abfd, tail);
-         bfd_section_list_insert (abfd, &abfd->sections, group);
+         bfd_section_list_remove (abfd, group);
+         bfd_section_list_insert_before (abfd, abfd->sections, group);
 
          elf_next_in_group (group) = sec;
 
index c84e9da6f7e020fb8c4bcd655c61d425a2966430..6fef11846859137314845f2c2f50eda27e36c113 100644 (file)
@@ -8870,7 +8870,6 @@ _bfd_mips_elf_link_hash_table_create (bfd *abfd)
 bfd_boolean
 _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 {
-  asection **secpp;
   asection *o;
   struct bfd_link_order *p;
   asection *reginfo_sec, *mdebug_sec, *gptab_data_sec, *gptab_bss_sec;
@@ -9285,11 +9284,7 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info)
              o->link_order_head = NULL;
 
              /* Really remove the section.  */
-             for (secpp = &abfd->sections;
-                  *secpp != o;
-                  secpp = &(*secpp)->next)
-               ;
-             bfd_section_list_remove (abfd, secpp);
+             bfd_section_list_remove (abfd, o);
              --abfd->section_count;
 
              continue;
index 788b03484e3884fb5b1ed5ea985133324ea53f6e..7e0b013b3e21f9e1ab52b2b0e2678847080030b8 100644 (file)
@@ -77,7 +77,7 @@ _bfd_new_bfd (void)
       return NULL;
     }
   nbfd->sections = NULL;
-  nbfd->section_tail = &nbfd->sections;
+  nbfd->section_last = NULL;
   nbfd->format = bfd_unknown;
   nbfd->my_archive = NULL;
   nbfd->origin = 0;
index 914d1825007e47a622a9f74034e9933694b553cd..45ede06fc62e8ee1ec533c4e795e9f703e9c5b15 100644 (file)
@@ -164,6 +164,9 @@ CODE_FRAGMENT
 .  {* The next section in the list belonging to the BFD, or NULL.  *}
 .  struct bfd_section *next;
 .
+.  {* The previous section in the list belonging to the BFD, or NULL.  *}
+.  struct bfd_section *prev;
+.
 .  {* The field flags contains attributes of the section. Some
 .     flags are read in from the object file, and some are
 .     synthesized from other information.  *}
@@ -538,31 +541,73 @@ CODE_FRAGMENT
 .{* Macros to handle insertion and deletion of a bfd's sections.  These
 .   only handle the list pointers, ie. do not adjust section_count,
 .   target_index etc.  *}
-.#define bfd_section_list_remove(ABFD, PS) \
+.#define bfd_section_list_remove(ABFD, S) \
+.  do                                                  \
+.    {                                                 \
+.      asection *_s = S;                               \
+.      asection *_next = _s->next;                     \
+.      asection *_prev = _s->prev;                     \
+.      if (_prev)                                      \
+.        _prev->next = _next;                          \
+.      else                                            \
+.        (ABFD)->sections = _next;                     \
+.      if (_next)                                      \
+.        {                                             \
+.          _next->prev = _prev;                                \
+.          _s->next = NULL;                            \
+.        }                                             \
+.      else                                            \
+.        (ABFD)->section_last = _prev;                 \
+.    }                                                 \
+.  while (0)
+.#define bfd_section_list_append(ABFD, S) \
 .  do                                                  \
 .    {                                                 \
-.      asection **_ps = PS;                            \
-.      asection *_s = *_ps;                            \
-.      *_ps = _s->next;                                        \
-.      if (_s->next == NULL)                           \
-.        (ABFD)->section_tail = _ps;                   \
+.      asection *_s = S;                               \
+.      bfd *_abfd = ABFD;                              \
+.      _s->next = NULL;                                        \
+.      if (_abfd->section_last)                                \
+.        {                                             \
+.          _s->prev = _abfd->section_last;             \
+.          _abfd->section_last->next = _s;             \
+.        }                                             \
+.      else                                            \
+.        _abfd->sections = _s;                         \
+.      _abfd->section_last = _s;                       \
+.    }                                                 \
+.  while (0)
+.#define bfd_section_list_insert_after(ABFD, A, S) \
+.  do                                                  \
+.    {                                                 \
+.      asection *_a = A;                               \
+.      asection *_s = S;                               \
+.      asection *_next = _a->next;                     \
+.      _s->next = _next;                               \
+.      _s->prev = _a;                                  \
+.      _a->next = _s;                                  \
+.      if (_next)                                      \
+.        _s->next->prev = _s;                          \
 .      else                                            \
-.        _s->next = NULL;                              \
+.        (ABFD)->section_last = _s;                    \
 .    }                                                 \
 .  while (0)
-.#define bfd_section_list_insert(ABFD, PS, S) \
+.#define bfd_section_list_insert_before(ABFD, B, S) \
 .  do                                                  \
 .    {                                                 \
-.      asection **_ps = PS;                            \
+.      asection *_b = B;                               \
 .      asection *_s = S;                               \
-.      _s->next = *_ps;                                        \
-.      *_ps = _s;                                      \
-.      if (_s->next == NULL)                           \
-.        (ABFD)->section_tail = &_s->next;             \
+.      asection *_prev = _b->prev;                     \
+.      _s->prev = _prev;                               \
+.      _s->next = _b;                                  \
+.      _b->prev = _s;                                  \
+.      if (_prev)                                      \
+.        _prev->next = _s;                             \
+.      else                                            \
+.        (ABFD)->sections = _s;                                \
 .    }                                                 \
 .  while (0)
-.#define bfd_section_removed_from_list(ABFD, S)        \
-.  ((S)->next == NULL && &(S)->next != (ABFD)->section_tail)
+.#define bfd_section_removed_from_list(ABFD, S) \
+.  ((S)->next == NULL && (S) != (ABFD)->section_last)
 .
 */
 
@@ -592,8 +637,8 @@ static const asymbol global_syms[] =
 #define STD_SECTION(SEC, FLAGS, SYM, NAME, IDX)                                \
   const asymbol * const SYM = (asymbol *) &global_syms[IDX];           \
   asection SEC =                                                       \
-    /* name, id,  index, next, flags, user_set_vma,                  */        \
-    { NAME,  IDX, 0,     NULL, FLAGS, 0,                               \
+    /* name, id,  index, next, prev, flags, user_set_vma,            */        \
+    { NAME,  IDX, 0,     NULL, NULL, FLAGS, 0,                         \
                                                                        \
     /* linker_mark, linker_has_input, gc_mark, segment_mark,         */        \
        0,           0,                1,       0,                      \
@@ -705,8 +750,7 @@ bfd_section_init (bfd *abfd, asection *newsect)
 
   section_id++;
   abfd->section_count++;
-  *abfd->section_tail = newsect;
-  abfd->section_tail = &newsect->next;
+  bfd_section_list_append (abfd, newsect);
   return newsect;
 }
 
@@ -736,7 +780,7 @@ void
 bfd_section_list_clear (bfd *abfd)
 {
   abfd->sections = NULL;
-  abfd->section_tail = &abfd->sections;
+  abfd->section_last = NULL;
   abfd->section_count = 0;
   memset (abfd->section_htab.table, 0,
          abfd->section_htab.size * sizeof (struct bfd_hash_entry *));
index bf907923939c4a71f7845350aae406d5c36ccd98..1b17d3eacdae78adac15fbf763d1815b9b68ca20 100644 (file)
@@ -832,7 +832,6 @@ sunos_add_dynamic_symbols (bfd *abfd,
   bfd *dynobj;
   struct sunos_dynamic_info *dinfo;
   unsigned long need;
-  asection **ps;
 
   /* Make sure we have all the required sections.  */
   if (info->hash->creator == abfd->xvec)
@@ -856,12 +855,18 @@ sunos_add_dynamic_symbols (bfd *abfd,
      want, because that one still implies that the section takes up
      space in the output file.  If this is the first object we have
      seen, we must preserve the dynamic sections we just created.  */
-  for (ps = &abfd->sections; *ps != NULL; )
+  if (abfd != dynobj)
+    abfd->sections = NULL;
+  else
     {
-      if (abfd != dynobj || ((*ps)->flags & SEC_LINKER_CREATED) == 0)
-       bfd_section_list_remove (abfd, ps);
-      else
-       ps = &(*ps)->next;
+      asection *s, *n;
+
+      for (s = abfd->sections; s != NULL; s = n)
+       {
+         n = s->next;
+         if ((s->flags & SEC_LINKER_CREATED) == 0)
+           bfd_section_list_remove (abfd, s);
+       }
     }
 
   /* The native linker seems to just ignore dynamic objects when -r is
index 10c48430419413d9f8e643a861e8c5ed20e72ac6..127ac3d67d525a4793bcedd41811f8e862d34ad1 100644 (file)
@@ -5454,20 +5454,18 @@ _bfd_xcoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
                    saw_contents = TRUE;
                  else
                    {
-                     asection *n, **st;
+                     asection *n;
 
                      /* Create a pad section and place it before the section
                         that needs padding.  This requires unlinking and
                         relinking the bfd's section list.  */
 
-                     st = abfd->section_tail;
                      n = bfd_make_section_anyway (abfd, ".pad");
                      n->flags = SEC_HAS_CONTENTS;
                      n->alignment_power = 0;
 
-                     BFD_ASSERT (*st == n);
-                     bfd_section_list_remove (abfd, st);
-                     bfd_section_list_insert (abfd, op, n);
+                     bfd_section_list_remove (abfd, n);
+                     bfd_section_list_insert_before (abfd, *op, n);
 
                      op = &n->next;
                      saw_contents = FALSE;
index 17a62ed7b8bb34b7275b69447d8826a4fd2e8a6a..369c5e2e9d568ffb8735c4142bbfbeebc9741871 100644 (file)
@@ -1,3 +1,8 @@
+2005-05-02  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * write.c (write_object_file): Use bfd_section_double_list_remove
+       to remove sections.
+
 2005-05-02  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * doc/Makefile.am (gasver.texi): Correct quoting.
index 417e0e971ea970bac8795dc5a52438b56e2397ca..7b77a29bf7fe0efe673c59216d1e4366480aa629 100644 (file)
@@ -1471,20 +1471,11 @@ write_object_file (void)
 #ifdef BFD_ASSEMBLER
   /* Remove the sections created by gas for its own purposes.  */
   {
-    asection **seclist;
     int i;
 
-    seclist = &stdoutput->sections;
-    while (*seclist)
-      {
-       if (*seclist == reg_section || *seclist == expr_section)
-         {
-           bfd_section_list_remove (stdoutput, seclist);
-           stdoutput->section_count--;
-         }
-       else
-         seclist = &(*seclist)->next;
-      }
+    bfd_section_list_remove (stdoutput, reg_section);
+    bfd_section_list_remove (stdoutput, expr_section);
+    stdoutput->section_count -= 2;
     i = 0;
     bfd_map_over_sections (stdoutput, renumber_sections, &i);
   }
index 932ab5600280f83b633fac8deb19bd45750c1977..938f62e59cbc6c46d68a2e3f65e88fcb0febe8a6 100644 (file)
@@ -1,3 +1,13 @@
+2005-05-02  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * emultempl/elf32.em (gld${EMULATION_NAME}_strip_empty_section):
+       Updated for bfd_section_list_remove change.
+       * ldlang.c (lang_insert_orphan): Likewise.
+       (strip_excluded_output_sections): Likewise.
+       (sort_sections_by_lma): New.
+       (lang_check_section_addresses): Sort the sections before
+       checking addresses.
+
 2005-04-29  Ralf Corsepius <ralf.corsepius@rtems.org>
 
        * configure.tgt: Add h8300*-*-rtemscoff.
index 9bcafef232961ae9ff6317490538c14228eec93e..2e1dac1a4cbec81fab86a56714059ae9bdef26eb 100644 (file)
@@ -1542,17 +1542,13 @@ gld${EMULATION_NAME}_strip_empty_sections (void)
          if (os == abs_output_section || os->constraint == -1)
            continue;
          s = os->bfd_section;
-         if (s != NULL && s->size == 0 && (s->flags & SEC_KEEP) == 0)
+         if (s != NULL
+             && s->size == 0
+             && (s->flags & SEC_KEEP) == 0
+             && !bfd_section_removed_from_list (output_bfd, s))
            {
-             asection **p;
-
-             for (p = &output_bfd->sections; *p; p = &(*p)->next)
-               if (*p == s)
-                 {
-                   bfd_section_list_remove (output_bfd, p);
-                   output_bfd->section_count--;
-                   break;
-                 }
+             bfd_section_list_remove (output_bfd, s);
+             output_bfd->section_count--;
            }
        }
     }
index 2568feda9d202ff3f7e153a429cd0d9209f7bc3e..895eded0bbd1b7b80180f93ef13d0ee6a68437c7 100644 (file)
@@ -1202,7 +1202,6 @@ lang_insert_orphan (lang_input_statement_type *file,
   etree_type *load_base;
   lang_output_section_statement_type *os;
   lang_output_section_statement_type **os_tail;
-  asection **bfd_tail;
 
   /* Start building a list of statements for this section.
      First save the current statement pointer.  */
@@ -1256,7 +1255,6 @@ lang_insert_orphan (lang_input_statement_type *file,
 
   os_tail = ((lang_output_section_statement_type **)
             lang_output_section_statement.tail);
-  bfd_tail = output_bfd->section_tail;
   os = lang_enter_output_section_statement (secname, address, 0, NULL, NULL,
                                            load_base, 0);
 
@@ -1288,7 +1286,7 @@ lang_insert_orphan (lang_input_statement_type *file,
 
   if (after != NULL && os->bfd_section != NULL)
     {
-      asection *snew;
+      asection *snew, *as;
 
       snew = os->bfd_section;
 
@@ -1314,12 +1312,15 @@ lang_insert_orphan (lang_input_statement_type *file,
       if (place->section == NULL)
        place->section = &output_bfd->sections;
 
-      /* Unlink the section.  */
-      ASSERT (*bfd_tail == snew);
-      bfd_section_list_remove (output_bfd, bfd_tail);
+      as = *place->section;
+      if (as != snew && as->prev != snew)
+       {
+         /* Unlink the section.  */
+         bfd_section_list_remove (output_bfd, snew);
 
-      /* Now tack it back on in the right place.  */
-      bfd_section_list_insert (output_bfd, place->section, snew);
+         /* Now tack it back on in the right place.  */
+         bfd_section_list_insert_before (output_bfd, as, snew);
+       }
 
       /* Save the end of this list.  Further ophans of this type will
         follow the one we've just added.  */
@@ -3044,17 +3045,12 @@ strip_excluded_output_sections (void)
       s = os->bfd_section;
       if (s != NULL && (s->flags & SEC_EXCLUDE) != 0)
        {
-         asection **p;
-
          os->bfd_section = NULL;
-
-         for (p = &output_bfd->sections; *p; p = &(*p)->next)
-           if (*p == s)
-             {
-               bfd_section_list_remove (output_bfd, p);
-               output_bfd->section_count--;
-               break;
-             }
+         if (!bfd_section_removed_from_list (output_bfd, s))
+           {
+             bfd_section_list_remove (output_bfd, s);
+             output_bfd->section_count--;
+           }
        }
     }
 }
@@ -3683,6 +3679,22 @@ size_input_section
   return dot;
 }
 
+static int
+sort_sections_by_lma (const void *arg1, const void *arg2)
+{
+  const asection *sec1 = *(const asection **) arg1;
+  const asection *sec2 = *(const asection **) arg2;
+
+  if (bfd_section_lma (sec1->owner, sec1)
+      < bfd_section_lma (sec2->owner, sec2))
+    return -1;
+  else if (bfd_section_lma (sec1->owner, sec1)
+          > bfd_section_lma (sec2->owner, sec2))
+    return 1;
+
+  return 0;
+}
+
 #define IGNORE_SECTION(s) \
   ((s->flags & SEC_NEVER_LOAD) != 0                            \
    || (s->flags & SEC_ALLOC) == 0                              \
@@ -3696,52 +3708,62 @@ size_input_section
 static void
 lang_check_section_addresses (void)
 {
-  asection *s;
+  asection *s, *os;
+  asection **sections, **spp;
+  unsigned int count;
+  bfd_vma s_start;
+  bfd_vma s_end;
+  bfd_vma os_start;
+  bfd_vma os_end;
+  bfd_size_type amt;
+
+  if (bfd_count_sections (output_bfd) <= 1)
+    return;
+
+  amt = bfd_count_sections (output_bfd) * sizeof (asection *);
+  sections = xmalloc (amt);
 
   /* Scan all sections in the output list.  */
+  count = 0;
   for (s = output_bfd->sections; s != NULL; s = s->next)
     {
-      asection *os;
-
-      /* Ignore sections which are not loaded or which have no contents.  */
+      /* Only consider loadable sections with real contents.  */
       if (IGNORE_SECTION (s) || s->size == 0)
        continue;
 
-      /* Once we reach section 's' stop our seach.  This prevents two
-        warning messages from being produced, one for 'section A overlaps
-        section B' and one for 'section B overlaps section A'.  */
-      for (os = output_bfd->sections; os != s; os = os->next)
-       {
-         bfd_vma s_start;
-         bfd_vma s_end;
-         bfd_vma os_start;
-         bfd_vma os_end;
-
-         /* Only consider loadable sections with real contents.  */
-         if (IGNORE_SECTION (os) || os->size == 0)
-           continue;
-
-         /* We must check the sections' LMA addresses not their
-            VMA addresses because overlay sections can have
-            overlapping VMAs but they must have distinct LMAs.  */
-         s_start = bfd_section_lma (output_bfd, s);
-         os_start = bfd_section_lma (output_bfd, os);
-         s_end = s_start + TO_ADDR (s->size) - 1;
-         os_end = os_start + TO_ADDR (os->size) - 1;
+      sections[count] = s;
+      count++;
+    }
+  
+  if (count <= 1)
+    return;
 
-         /* Look for an overlap.  */
-         if ((s_end < os_start) || (s_start > os_end))
-           continue;
+  qsort (sections, (size_t) count, sizeof (asection *),
+        sort_sections_by_lma);
 
-         einfo (
-_("%X%P: section %s [%V -> %V] overlaps section %s [%V -> %V]\n"),
-                s->name, s_start, s_end, os->name, os_start, os_end);
+  spp = sections;
+  s = *spp++;
+  s_start = bfd_section_lma (output_bfd, s);
+  s_end = s_start + TO_ADDR (s->size) - 1;
+  for (count--; count; count--)
+    {
+      /* We must check the sections' LMA addresses not their VMA
+        addresses because overlay sections can have overlapping VMAs
+        but they must have distinct LMAs.  */
+      os = s;
+      os_start = s_start; 
+      os_end = s_end;
+      s = *spp++;
+      s_start = bfd_section_lma (output_bfd, s);
+      s_end = s_start + TO_ADDR (s->size) - 1;
 
-         /* Once we have found one overlap for this section,
-            stop looking for others.  */
-         break;
-       }
+      /* Look for an overlap.  */
+      if (s_end >= os_start && s_start <= os_end)
+       einfo (_("%X%P: section %s [%V -> %V] overlaps section %s [%V -> %V]\n"),
+              s->name, s_start, s_end, os->name, os_start, os_end);
     }
+
+  free (sections);
 }
 
 /* Make sure the new address is within the region.  We explicitly permit the