summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl@lucon.org>2005-05-03 01:05:03 +0000
committerH.J. Lu <hjl@lucon.org>2005-05-03 01:05:03 +0000
commitfafb084693312837c2f2ca34e8e8072ffad5238d (patch)
treef2ce9fb7e0b875b80fc14665b2a83d83b6527f87
parentea5ff033e1c8ef9eeb8b74da7a8de6a3c96b14eb (diff)
downloadbinutils-redhat-fafb084693312837c2f2ca34e8e8072ffad5238d.tar.gz
bfd/
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.
-rw-r--r--bfd/ChangeLog33
-rw-r--r--bfd/bfd-in2.h91
-rw-r--r--bfd/bfd.c12
-rw-r--r--bfd/coffcode.h17
-rw-r--r--bfd/ecoff.c4
-rw-r--r--bfd/elf.c15
-rw-r--r--bfd/elf32-i370.c16
-rw-r--r--bfd/elf64-mmix.c7
-rw-r--r--bfd/elfxx-ia64.c8
-rw-r--r--bfd/elfxx-mips.c7
-rw-r--r--bfd/opncls.c2
-rw-r--r--bfd/section.c84
-rw-r--r--bfd/sunos.c17
-rw-r--r--bfd/xcofflink.c8
-rw-r--r--gas/ChangeLog5
-rw-r--r--gas/write.c15
-rw-r--r--ld/ChangeLog10
-rw-r--r--ld/emultempl/elf32.em16
-rw-r--r--ld/ldlang.c128
19 files changed, 315 insertions, 180 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index f4c8450d56..e99fd75da0 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,38 @@
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
_bfd_elf_get_sec_type_attr on sections from input files.
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 1e373f28fc..64a153fc33 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -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;
};
diff --git a/bfd/bfd.c b/bfd/bfd.c
index aacc5007be..7df66741da 100644
--- 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
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index cd4a371f33..cec3992146 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -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);
}
diff --git a/bfd/ecoff.c b/bfd/ecoff.c
index 4ece3c17a2..f84f5eaf13 100644
--- a/bfd/ecoff.c
+++ b/bfd/ecoff.c
@@ -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, */
diff --git a/bfd/elf.c b/bfd/elf.c
index 2af5a8964b..fac05e0d88 100644
--- 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;
}
}
diff --git a/bfd/elf32-i370.c b/bfd/elf32-i370.c
index 2166e8aaa7..3ad7b90f47 100644
--- a/bfd/elf32-i370.c
+++ b/bfd/elf32-i370.c
@@ -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;
}
diff --git a/bfd/elf64-mmix.c b/bfd/elf64-mmix.c
index c831d9fbe6..a690e7d2dd 100644
--- a/bfd/elf64-mmix.c
+++ b/bfd/elf64-mmix.c
@@ -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;
}
diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c
index de5793cac5..a483e2d193 100644
--- a/bfd/elfxx-ia64.c
+++ b/bfd/elfxx-ia64.c
@@ -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;
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index c84e9da6f7..6fef118468 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -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;
diff --git a/bfd/opncls.c b/bfd/opncls.c
index 788b03484e..7e0b013b3e 100644
--- a/bfd/opncls.c
+++ b/bfd/opncls.c
@@ -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;
diff --git a/bfd/section.c b/bfd/section.c
index 914d182500..45ede06fc6 100644
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -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 *));
diff --git a/bfd/sunos.c b/bfd/sunos.c
index bf90792393..1b17d3eacd 100644
--- a/bfd/sunos.c
+++ b/bfd/sunos.c
@@ -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
diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c
index 10c4843041..127ac3d67d 100644
--- a/bfd/xcofflink.c
+++ b/bfd/xcofflink.c
@@ -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;
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 17a62ed7b8..369c5e2e9d 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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.
diff --git a/gas/write.c b/gas/write.c
index 417e0e971e..7b77a29bf7 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -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);
}
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 932ab56002..938f62e59c 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -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.
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 9bcafef232..2e1dac1a4c 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -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--;
}
}
}
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 2568feda9d..895eded0bb 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -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