diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 33 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 91 | ||||
-rw-r--r-- | bfd/bfd.c | 12 | ||||
-rw-r--r-- | bfd/coffcode.h | 17 | ||||
-rw-r--r-- | bfd/ecoff.c | 4 | ||||
-rw-r--r-- | bfd/elf.c | 15 | ||||
-rw-r--r-- | bfd/elf32-i370.c | 16 | ||||
-rw-r--r-- | bfd/elf64-mmix.c | 7 | ||||
-rw-r--r-- | bfd/elfxx-ia64.c | 8 | ||||
-rw-r--r-- | bfd/elfxx-mips.c | 7 | ||||
-rw-r--r-- | bfd/opncls.c | 2 | ||||
-rw-r--r-- | bfd/section.c | 84 | ||||
-rw-r--r-- | bfd/sunos.c | 17 | ||||
-rw-r--r-- | bfd/xcofflink.c | 8 |
14 files changed, 216 insertions, 105 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index f4c8450d56f..e99fd75da0a 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 1e373f28fc2..64a153fc339 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 aacc5007be9..7df66741dac 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 cd4a371f33a..cec3992146d 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 = ¤t->next; free (section_list); } diff --git a/bfd/ecoff.c b/bfd/ecoff.c index 4ece3c17a21..f84f5eaf136 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 2af5a8964b6..fac05e0d886 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 2166e8aaa7e..3ad7b90f47b 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 c831d9fbe64..a690e7d2dd9 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 de5793cac51..a483e2d193c 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 c84e9da6f7e..6fef1184685 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 788b03484e3..7e0b013b3e2 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 914d1825007..45ede06fc62 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 bf907923939..1b17d3eacda 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 10c48430419..127ac3d67d5 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; |