+2005-05-04 Alan Modra <amodra@bigpond.net.au>
+
+ * section.c (struct bfd_section): Replace link_order_head and
+ link_order_tail with map_head and map_tail union.
+ (STD_SECTION): Update.
+ (_bfd_strip_section_from_output): Delete.
+ * aoutx.h: Update throughout for above changes.
+ * coff-ppc.c: Likewise.
+ * cofflink.c: Likewise.
+ * ecoff.c: Likewise.
+ * elf-eh-frame.c: Likewise.
+ * elf-m10300.c: Likewise.
+ * elf.c: Likewise.
+ * elf32-arm.c: Likewise.
+ * elf32-cris.c: Likewise.
+ * elf32-hppa.c: Likewise.
+ * elf32-i386.c: Likewise.
+ * elf32-m32r.c: Likewise.
+ * elf32-m68hc1x.c: Likewise.
+ * elf32-m68k.c: Likewise.
+ * elf32-ppc.c: Likewise.
+ * elf32-s390.c: Likewise.
+ * elf32-sh.c: Likewise.
+ * elf32-vax.c: Likewise.
+ * elf32-xtensa.c: Likewise.
+ * elf64-alpha.c: Likewise.
+ * elf64-hppa.c: Likewise.
+ * elf64-ppc.c: Likewise.
+ * elf64-s390.c: Likewise.
+ * elf64-sh64.c: Likewise.
+ * elf64-x86-64.c: Likewise.
+ * elflink.c: Likewise.
+ * elfxx-ia64.c: Likewise.
+ * elfxx-mips.c: Likewise.
+ * elfxx-sparc.c: Likewise.
+ * linker.c: Likewise.
+ * merge.c: Likewise.
+ * pdp11.c: Likewise.
+ * xcofflink.c: Likewise.
+ * elflink.c (bfd_boolean bfd_elf_size_dynsym_hash_dynstr): Split
+ out from bfd_elf_size_dynamic_sections.
+ * bfd-in.h (bfd_boolean bfd_elf_size_dynsym_hash_dynstr): Declare.
+ * bfd-in2.h: Regenerate.
+
2005-05-04 Nick Clifton <nickc@redhat.com>
* COPYING, aix386-core.c, aix5ppc-core.c, aout-adobe.c,
{
if (obj_textsec (abfd) != NULL)
trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
- ->link_order_head)
+ ->map_head.link_order)
* obj_reloc_entry_size (abfd));
if (obj_datasec (abfd) != NULL)
drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
- ->link_order_head)
+ ->map_head.link_order)
* obj_reloc_entry_size (abfd));
}
include. */
for (o = abfd->sections; o != NULL; o = o->next)
{
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
if (p->type == bfd_indirect_link_order)
p->u.indirect.section->linker_mark = TRUE;
}
have_link_order_relocs = FALSE;
for (o = abfd->sections; o != NULL; o = o->next)
{
- for (p = o->link_order_head;
+ for (p = o->map_head.link_order;
p != NULL;
p = p->next)
{
{
for (o = abfd->sections; o != NULL; o = o->next)
{
- for (p = o->link_order_head;
+ for (p = o->map_head.link_order;
p != NULL;
p = p->next)
{
(bfd *, struct bfd_link_needed_list **);
extern bfd_boolean bfd_elf_size_dynamic_sections
(bfd *, const char *, const char *, const char *, const char * const *,
- struct bfd_link_info *, struct bfd_section **, struct bfd_elf_version_tree *);
+ struct bfd_link_info *, struct bfd_section **,
+ struct bfd_elf_version_tree *);
+extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr
+ (bfd *, struct bfd_link_info *);
extern void bfd_elf_set_dt_needed_name
(bfd *, const char *);
extern const char *bfd_elf_get_dt_soname
(bfd *, struct bfd_link_needed_list **);
extern bfd_boolean bfd_elf_size_dynamic_sections
(bfd *, const char *, const char *, const char *, const char * const *,
- struct bfd_link_info *, struct bfd_section **, struct bfd_elf_version_tree *);
+ struct bfd_link_info *, struct bfd_section **,
+ struct bfd_elf_version_tree *);
+extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr
+ (bfd *, struct bfd_link_info *);
extern void bfd_elf_set_dt_needed_name
(bfd *, const char *);
extern const char *bfd_elf_get_dt_soname
struct bfd_symbol *symbol;
struct bfd_symbol **symbol_ptr_ptr;
- struct bfd_link_order *link_order_head;
- struct bfd_link_order *link_order_tail;
+ /* Early in the link process, map_head and map_tail are used to build
+ a list of input sections attached to an output section. Later,
+ output sections use these fields for a list of bfd_link_order
+ structs. */
+ union {
+ struct bfd_link_order *link_order;
+ struct bfd_section *s;
+ } map_head, map_tail;
} asection;
/* These sections are global, and are managed by BFD. The application
#define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \
BFD_SEND (obfd, _bfd_copy_private_section_data, \
(ibfd, isection, obfd, osection))
-void _bfd_strip_section_from_output
- (struct bfd_link_info *info, asection *section);
-
bfd_boolean bfd_generic_is_group_section (bfd *, const asection *sec);
bfd_boolean bfd_generic_discard_group (bfd *abfd, asection *group);
o->reloc_count = 0;
o->lineno_count = 0;
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
{
if (p->type == bfd_indirect_link_order)
{
for (o = abfd->sections; o != NULL; o = o->next)
{
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
{
if (p->type == bfd_indirect_link_order
&& (bfd_get_flavour (p->u.indirect.section->owner)
{
o->reloc_count = 0;
o->lineno_count = 0;
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
{
if (p->type == bfd_indirect_link_order)
{
for (o = abfd->sections; o != NULL; o = o->next)
{
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
{
if (p->type == bfd_indirect_link_order
&& bfd_family_coff (p->u.indirect.section->owner))
NULL,
/* symbol_ptr_ptr, */
NULL,
- /* link_order_head, link_order_tail */
- NULL, NULL
+ /* map_head, map_tail */
+ { NULL }, { NULL }
};
/* Create an ECOFF object. */
for (o = abfd->sections; o != NULL; o = o->next)
{
o->reloc_count = 0;
- for (p = o->link_order_head;
+ for (p = o->map_head.link_order;
p != NULL;
p = p->next)
if (p->type == bfd_indirect_link_order)
for (o = abfd->sections; o != NULL; o = o->next)
{
- for (p = o->link_order_head;
+ for (p = o->map_head.link_order;
p != NULL;
p = p->next)
{
/* This function is called from size_dynamic_sections.
It needs to decide whether .eh_frame_hdr should be output or not,
- because later on it is too late for calling _bfd_strip_section_from_output,
- since dynamic symbol table has been sized. */
+ because when the dynamic symbol table has been sized it is too late
+ to strip sections. */
bfd_boolean
_bfd_elf_maybe_strip_eh_frame_hdr (struct bfd_link_info *info)
if (abfd == NULL)
{
- _bfd_strip_section_from_output (info, hdr_info->hdr_sec);
+ hdr_info->hdr_sec->flags |= SEC_EXCLUDE;
hdr_info->hdr_sec = NULL;
return TRUE;
}
if (strip)
{
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
continue;
}
struct bfd_link_order *l;
asection *elt;
- for (l = asect->link_order_head; l != NULL; l = l->next)
+ for (l = asect->map_head.link_order; l != NULL; l = l->next)
if (l->type == bfd_indirect_link_order
&& (elt = elf_next_in_group (l->u.indirect.section)) != NULL)
do
struct bfd_link_order *o;
this_hdr->sh_size = 0;
- for (o = asect->link_order_head; o != NULL; o = o->next)
+ for (o = asect->map_head.link_order; o != NULL; o = o->next)
if (this_hdr->sh_size < o->offset + o->size)
this_hdr->sh_size = o->offset + o->size;
if (this_hdr->sh_size)
/* If this is a relocatable link, then the above did nothing because
SEC is the output section. Look through the input sections
instead. */
- for (l = sec->link_order_head; l != NULL; l = l->next)
+ for (l = sec->map_head.link_order; l != NULL; l = l->next)
if (l->type == bfd_indirect_link_order
&& (elt = elf_next_in_group (l->u.indirect.section)) != NULL)
do
/* Find out what the corresponding section in output
is. */
- for (p = sec->link_order_head; p != NULL; p = p->next)
+ for (p = sec->map_head.link_order; p != NULL; p = p->next)
{
s = p->u.indirect.section;
if (p->type == bfd_indirect_link_order
struct bfd_link_order *o;
bfd_vma tbss_size = 0;
- for (o = sec->link_order_head; o != NULL; o = o->next)
+ for (o = sec->map_head.link_order; o != NULL; o = o->next)
if (tbss_size < o->offset + o->size)
tbss_size = o->offset + o->size;
if (strip)
{
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
continue;
}
if (strip)
{
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
continue;
}
adjust_dynamic_symbol is called, and it is that
function which decides whether anything needs to go
into these sections. */
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
continue;
}
/* We can't use output_bfd->section_count here to find the top output
section index as some sections may have been removed, and
- _bfd_strip_section_from_output doesn't renumber the indices. */
+ strip_excluded_output_sections doesn't renumber the indices. */
for (section = output_bfd->sections, top_index = 0;
section != NULL;
section = section->next)
function which decides whether anything needs to go
into these sections. */
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
continue;
}
adjust_dynamic_symbol is called, and it is that
function which decides whether anything needs to go
into these sections. */
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
continue;
}
/* We can't use output_bfd->section_count here to find the top output
section index as some sections may have been removed, and
- _bfd_strip_section_from_output doesn't renumber the indices. */
+ strip_excluded_output_sections doesn't renumber the indices. */
for (section = output_bfd->sections, top_index = 0;
section != NULL;
section = section->next)
if (strip)
{
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
continue;
}
if (s->size == 0)
{
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
continue;
}
function which decides whether anything needs to go
into these sections. */
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
continue;
}
function which decides whether anything needs to go
into these sections. */
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
continue;
}
if (strip)
{
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
continue;
}
}
if (strip)
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
else
{
/* Allocate memory for the section contents. */
}
if (strip)
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
else
{
/* Allocate memory for the section contents. */
}
}
- for (p = o->link_order_head;
+ for (p = o->map_head.link_order;
p != (struct bfd_link_order *) NULL;
p = p->next)
{
/* Skip this section later on (I don't think this currently
matters, but someday it might). */
- o->link_order_head = (struct bfd_link_order *) NULL;
+ o->map_head.link_order = (struct bfd_link_order *) NULL;
mdebug_sec = o;
}
if (strip)
{
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
continue;
}
elf_link_hash_traverse (&htab->elf, func_desc_adjust, info);
if (htab->sfpr->size == 0)
- _bfd_strip_section_from_output (info, htab->sfpr);
+ htab->sfpr->flags |= SEC_EXCLUDE;
return TRUE;
}
if (s->size == 0)
{
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
continue;
}
if (s != NULL && s != htab->got)
{
if (s->size == 0)
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
else
{
s->contents = bfd_zalloc (ibfd, s->size);
if (s != NULL)
{
if (s->size == 0)
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
else
{
s->contents = bfd_zalloc (ibfd, s->size);
/* We can't use output_bfd->section_count here to find the top output
section index as some sections may have been removed, and
- _bfd_strip_section_from_output doesn't renumber the indices. */
+ strip_excluded_output_sections doesn't renumber the indices. */
for (section = output_bfd->sections, top_index = 0;
section != NULL;
section = section->next)
function which decides whether anything needs to go
into these sections. */
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
continue;
}
if (strip)
{
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
continue;
}
function which decides whether anything needs to go
into these sections. */
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
continue;
}
if (elf_hash_table (info)->dynamic_sections_created)
{
- bfd_size_type dynsymcount;
unsigned long section_sym_count;
asection *s;
- size_t bucketcount = 0;
- size_t hash_entry_size;
- unsigned int dtagcount;
/* Set up the version definition section. */
s = bfd_get_section_by_name (dynobj, ".gnu.version_d");
verdefs = verdefs->next;
if (verdefs == NULL && !info->create_default_symver)
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
else
{
unsigned int cdefs;
&sinfo);
if (elf_tdata (output_bfd)->verref == NULL)
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
else
{
Elf_Internal_Verneed *t;
}
}
+ if ((elf_tdata (output_bfd)->cverrefs == 0
+ && elf_tdata (output_bfd)->cverdefs == 0)
+ || _bfd_elf_link_renumber_dynsyms (output_bfd, info,
+ §ion_sym_count) == 0)
+ {
+ s = bfd_get_section_by_name (dynobj, ".gnu.version");
+ s->flags |= SEC_EXCLUDE;
+ }
+ }
+ return TRUE;
+}
+
+bfd_boolean
+bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info)
+{
+ if (!is_elf_hash_table (info->hash))
+ return TRUE;
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ bfd *dynobj;
+ const struct elf_backend_data *bed;
+ asection *s;
+ bfd_size_type dynsymcount;
+ unsigned long section_sym_count;
+ size_t bucketcount = 0;
+ size_t hash_entry_size;
+ unsigned int dtagcount;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
/* Assign dynsym indicies. In a shared library we generate a
section symbol for each output section, which come first.
Next come all of the back-end allocated local dynamic syms,
/* Work out the size of the symbol version section. */
s = bfd_get_section_by_name (dynobj, ".gnu.version");
BFD_ASSERT (s != NULL);
- if (dynsymcount == 0
- || (verdefs == NULL && elf_tdata (output_bfd)->verref == NULL
- && !info->create_default_symver))
- {
- _bfd_strip_section_from_output (info, s);
- /* The DYNSYMCOUNT might have changed if we were going to
- output a dynamic symbol table entry for S. */
- dynsymcount = _bfd_elf_link_renumber_dynsyms (output_bfd, info,
- §ion_sym_count);
- }
- else
+ if (dynsymcount != 0
+ && (s->flags & SEC_EXCLUDE) == 0)
{
s->size = dynsymcount * sizeof (Elf_External_Versym);
s->contents = bfd_zalloc (output_bfd, s->size);
section as we went along in elf_link_add_object_symbols. */
s = bfd_get_section_by_name (dynobj, ".dynsym");
BFD_ASSERT (s != NULL);
+ bed = get_elf_backend_data (output_bfd);
s->size = dynsymcount * bed->s->sizeof_sym;
if (dynsymcount != 0)
count = reldyn->size / ext_size;
size = 0;
- for (lo = reldyn->link_order_head; lo != NULL; lo = lo->next)
+ for (lo = reldyn->map_head.link_order; lo != NULL; lo = lo->next)
if (lo->type == bfd_indirect_link_order)
{
asection *o = lo->u.indirect.section;
else
r_sym_mask = ~(bfd_vma) 0xffffffff;
- for (lo = reldyn->link_order_head; lo != NULL; lo = lo->next)
+ for (lo = reldyn->map_head.link_order; lo != NULL; lo = lo->next)
if (lo->type == bfd_indirect_link_order)
{
bfd_byte *erel, *erelend;
qsort (s_non_relative, count - ret, sort_elt, elf_link_sort_cmp2);
- for (lo = reldyn->link_order_head; lo != NULL; lo = lo->next)
+ for (lo = reldyn->map_head.link_order; lo != NULL; lo = lo->next)
if (lo->type == bfd_indirect_link_order)
{
bfd_byte *erel, *erelend;
seen_other = 0;
seen_linkorder = 0;
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
{
if (p->type == bfd_indirect_link_order
&& (bfd_get_flavour ((sub = p->u.indirect.section->owner))
xmalloc (seen_linkorder * sizeof (struct bfd_link_order *));
seen_linkorder = 0;
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
{
sections[seen_linkorder++] = p;
}
struct bfd_elf_section_data *esdo = elf_section_data (o);
o->reloc_count = 0;
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
{
unsigned int reloc_count = 0;
struct bfd_elf_section_data *esdi = NULL;
{
struct bfd_link_order *o;
- for (o = sec->link_order_head; o != NULL; o = o->next)
+ for (o = sec->map_head.link_order; o != NULL; o = o->next)
if (size < o->offset + o->size)
size = o->offset + o->size;
}
sub->output_has_begun = FALSE;
for (o = abfd->sections; o != NULL; o = o->next)
{
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
{
if (p->type == bfd_indirect_link_order
&& (bfd_get_flavour ((sub = p->u.indirect.section->owner))
int i;
for (i = m->count - 1; i >= 0; --i)
{
- struct bfd_link_order *order = m->sections[i]->link_order_head;
+ struct bfd_link_order *order = m->sections[i]->map_head.link_order;
while (order)
{
if (order->type == bfd_indirect_link_order)
}
if (strip)
- _bfd_strip_section_from_output (info, sec);
+ sec->flags |= SEC_EXCLUDE;
else
{
/* Allocate memory for the section contents. */
/* Skip this section later on (I don't think this currently
matters, but someday it might). */
- s->link_order_head = NULL;
+ s->map_head.link_order = NULL;
if (epdr != NULL)
free (epdr);
if (strip)
{
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
continue;
}
/* We have found the .reginfo section in the output file.
Look through all the link_orders comprising it and merge
the information together. */
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
{
asection *input_section;
bfd *input_bfd;
/* Skip this section later on (I don't think this currently
matters, but someday it might). */
- o->link_order_head = NULL;
+ o->map_head.link_order = NULL;
reginfo_sec = o;
}
return FALSE;
}
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
{
asection *input_section;
bfd *input_bfd;
/* Skip this section later on (I don't think this currently
matters, but someday it might). */
- o->link_order_head = NULL;
+ o->map_head.link_order = NULL;
mdebug_sec = o;
}
not used in executables files. */
if (! info->relocatable)
{
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
{
asection *input_section;
/* Skip this section later on (I don't think this
currently matters, but someday it might). */
- o->link_order_head = NULL;
+ o->map_head.link_order = NULL;
/* Really remove the section. */
bfd_section_list_remove (abfd, o);
tab[0].gt_header.gt_unused = 0;
/* Combine the input sections. */
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
{
asection *input_section;
bfd *input_bfd;
/* Skip this section later on (I don't think this currently
matters, but someday it might). */
- o->link_order_head = NULL;
+ o->map_head.link_order = NULL;
}
}
if (strip)
{
- _bfd_strip_section_from_output (info, s);
+ s->flags |= SEC_EXCLUDE;
continue;
}
of the <<bfd>> structure.
Each section in the output file will have a list of
- <<link_order>> structures attached to the <<link_order_head>>
+ <<link_order>> structures attached to the <<map_head.link_order>>
field (the <<link_order>> structure is defined in
<<bfdlink.h>>). These structures describe how to create the
contents of the output section in terms of the contents of
/* Mark all sections which will be included in the output file. */
for (o = abfd->sections; o != NULL; o = o->next)
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
if (p->type == bfd_indirect_link_order)
p->u.indirect.section->linker_mark = TRUE;
for (o = abfd->sections; o != NULL; o = o->next)
{
o->reloc_count = 0;
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
{
if (p->type == bfd_section_reloc_link_order
|| p->type == bfd_symbol_reloc_link_order)
/* Handle all the link order information for the sections. */
for (o = abfd->sections; o != NULL; o = o->next)
{
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
{
switch (p->type)
{
new->type = bfd_undefined_link_order;
- if (section->link_order_tail != NULL)
- section->link_order_tail->next = new;
+ if (section->map_tail.link_order != NULL)
+ section->map_tail.link_order->next = new;
else
- section->link_order_head = new;
- section->link_order_tail = new;
+ section->map_head.link_order = new;
+ section->map_tail.link_order = new;
return new;
}
with _bfd_merge_section. */
bfd_boolean
-_bfd_merge_sections (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info,
- void *xsinfo, void (*remove_hook) (bfd *, asection *))
+_bfd_merge_sections (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ void *xsinfo,
+ void (*remove_hook) (bfd *, asection *))
{
struct sec_merge_info *sinfo;
the hash table at all. */
for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
if (secinfo->first_str == NULL)
- _bfd_strip_section_from_output (info, secinfo->sec);
+ secinfo->sec->flags |= SEC_EXCLUDE;
}
return TRUE;
{
if (obj_textsec (abfd) != NULL)
trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
- ->link_order_head)
+ ->map_head.link_order)
* obj_reloc_entry_size (abfd));
if (obj_datasec (abfd) != NULL)
drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
- ->link_order_head)
+ ->map_head.link_order)
* obj_reloc_entry_size (abfd));
}
include. */
for (o = abfd->sections; o != NULL; o = o->next)
{
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
if (p->type == bfd_indirect_link_order)
p->u.indirect.section->linker_mark = TRUE;
}
have_link_order_relocs = FALSE;
for (o = abfd->sections; o != NULL; o = o->next)
{
- for (p = o->link_order_head;
+ for (p = o->map_head.link_order;
p != NULL;
p = p->next)
{
{
for (o = abfd->sections; o != NULL; o = o->next)
{
- for (p = o->link_order_head;
+ for (p = o->map_head.link_order;
p != NULL;
p = p->next)
{
. struct bfd_symbol *symbol;
. struct bfd_symbol **symbol_ptr_ptr;
.
-. struct bfd_link_order *link_order_head;
-. struct bfd_link_order *link_order_tail;
+. {* Early in the link process, map_head and map_tail are used to build
+. a list of input sections attached to an output section. Later,
+. output sections use these fields for a list of bfd_link_order
+. structs. *}
+. union {
+. struct bfd_link_order *link_order;
+. struct bfd_section *s;
+. } map_head, map_tail;
.} asection;
.
.{* These sections are global, and are managed by BFD. The application
/* symbol_ptr_ptr, */ \
(struct bfd_symbol **) &SYM, \
\
- /* link_order_head, link_order_tail */ \
- NULL, NULL \
+ /* map_head, map_tail */ \
+ { NULL }, { NULL } \
}
STD_SECTION (bfd_com_section, SEC_IS_COMMON, bfd_com_symbol,
. (ibfd, isection, obfd, osection))
*/
-/*
-FUNCTION
- _bfd_strip_section_from_output
-
-SYNOPSIS
- void _bfd_strip_section_from_output
- (struct bfd_link_info *info, asection *section);
-
-DESCRIPTION
- Remove @var{section} from the output. If the output section
- becomes empty, remove it from the output bfd.
-
- This function won't actually do anything except twiddle flags
- if called too late in the linking process, when it's not safe
- to remove sections.
-*/
-void
-_bfd_strip_section_from_output (struct bfd_link_info *info, asection *s)
-{
- asection *os;
- asection *is;
- bfd *abfd;
-
- s->flags |= SEC_EXCLUDE;
-
- /* If the section wasn't assigned to an output section, or the
- section has been discarded by the linker script, there's nothing
- more to do. */
- os = s->output_section;
- if (os == NULL || os->owner == NULL)
- return;
-
- /* If the output section has other (non-excluded) input sections, we
- can't remove it. */
- for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
- for (is = abfd->sections; is != NULL; is = is->next)
- if (is->output_section == os && (is->flags & SEC_EXCLUDE) == 0)
- return;
-
- /* If the output section is empty, flag it for removal too.
- See ldlang.c:strip_excluded_output_sections for the action. */
- os->flags |= SEC_EXCLUDE;
-}
-
/*
FUNCTION
bfd_generic_is_group_section
{
o->reloc_count = 0;
o->lineno_count = 0;
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
{
if (p->type == bfd_indirect_link_order)
{
for a single input file at once. */
for (o = abfd->sections; o != NULL; o = o->next)
{
- for (p = o->link_order_head; p != NULL; p = p->next)
+ for (p = o->map_head.link_order; p != NULL; p = p->next)
{
if (p->type == bfd_indirect_link_order
&& p->u.indirect.section->owner->xvec == abfd->xvec)
+2005-05-04 Alan Modra <amodra@bigpond.net.au>
+
+ * ldemul.c: Include bfdlink.h.
+ (ldemul_before_allocation): Assume before_allocation is non-zero.
+ (before_allocation_default): Call strip_excluded_output_sections.
+ * ldlang.c (stripped_excluded_sections): New variable.
+ (lang_add_section): Build input section list for each output
+ section, attached via map_head and map_tail pointers.
+ (strip_excluded_output_sections): Make global. Traverse the
+ input section lists to find which output sections can go. Clear
+ link_order pointers and set stripped_excluded_sections.
+ (lang_process): Call strip_excluded_output_sections.
+ * ldlang.h (strip_excluded_output_sections): Declare.
+ * ldwrite.c: Update throuhout for link_order_head -> map_head change.
+ * emultempl/aix.em (before_allocation): Call
+ strip_excluded_output_sections.
+ * emultempl/armcoff.em (before_allocation): Likewise.
+ * emultempl/beos.em (before_allocation): Likewise.
+ * emultempl/linux.em (before_allocation): Likewise.
+ * emultempl/pe.em (before_allocation): Likewise.
+ * emultempl/sunos.em (before_allocation): Likewise.
+ * emultempl/elf32.em (before_allocation): Likewise. Call
+ bfd_elf_size_dynsym_hash_dynstr too.
+ * emultempl/lnk960.em (lnk960_before_allocation): Delete.
+ (ld_lnk960): Use before_allocation_default.
+
2005-05-02 H.J. Lu <hongjiu.lu@intel.com>
* emultempl/elf32.em (gld${EMULATION_NAME}_strip_empty_section):
/* AIX emulation code for ${EMULATION_NAME}
Copyright 1991, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004
+ 2003, 2004, 2005
Free Software Foundation, Inc.
Written by Steve Chamberlain <sac@cygnus.com>
AIX support by Ian Lance Taylor <ian@cygnus.com>
&is->header.next);
}
}
+
+ if (!link_info.relocatable)
+ strip_excluded_output_sections ();
}
static char *
/* emulate the original gld for the given ${EMULATION_NAME}
Copyright 1991, 1993, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004 Free Software Foundation, Inc.
+ 2004, 2005 Free Software Foundation, Inc.
Written by Steve Chamberlain steve@cygnus.com
This file is part of GLD, the Gnu Linker.
/* We have seen it all. Allocate it, and carry on */
bfd_arm_allocate_interworking_sections (& link_info);
+
+ if (!link_info.relocatable)
+ strip_excluded_output_sections ();
}
static void
#endif /* TARGET_IS_ppcpe */
sort_sections (stat_ptr->head);
+
+ if (!link_info.relocatable)
+ strip_excluded_output_sections ();
}
\f
/* Place an orphan section. We use this to put sections with a '\$' in them
(const char * const *) command_line.auxiliary_filters,
&link_info, &sinterp, lang_elf_version_info)))
einfo ("%P%F: failed to set dynamic section sizes: %E\n");
+
${ELF_INTERPRETER_SET_DEFAULT}
/* Let the user override the dynamic linker we are using. */
if (command_line.interpreter != NULL
s->flags |= SEC_EXCLUDE;
}
}
+
+ if (!link_info.relocatable)
+ strip_excluded_output_sections ();
+
+ if (!bfd_elf_size_dynsym_hash_dynstr (output_bfd, &link_info))
+ einfo ("%P%F: failed to set dynamic section sizes: %E\n");
}
EOF
/* Linux a.out emulation code for ${EMULATION_NAME}
Copyright 1991, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004 Free Software Foundation, Inc.
+ 2003, 2004, 2005 Free Software Foundation, Inc.
Written by Steve Chamberlain <sac@cygnus.com>
Linux support by Eric Youngdale <ericy@cais.cais.com>
dynamic linking. */
if (! bfd_${EMULATION_NAME}_size_dynamic_sections (output_bfd, &link_info))
einfo ("%P%F: failed to set dynamic section sizes: %E\n");
+
+ strip_excluded_output_sections ();
}
static char *
add_on (syslib_list, lang_input_file_is_search_file_enum);
}
-static void
-lnk960_before_allocation (void)
-{
-}
-
static void
lnk960_after_allocation (void)
{
lnk960_after_allocation,
lnk960_set_output_arch,
lnk960_choose_target,
- lnk960_before_allocation,
+ before_allocation_default,
lnk960_get_script,
"lnk960",
"",
/* This file is is generated by a shell script. DO NOT EDIT! */
/* Handle embedded relocs for m68k.
- Copyright 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Copyright 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Written by Michael Sokolov <msokolov@ivan.Harhan.ORG>, based on generic.em
by Steve Chamberlain <steve@cygnus.com>, embedded relocs code based on
mipsecoff.em by Ian Lance Taylor <ian@cygnus.com>.
/* We have seen it all. Allocate it, and carry on. */
bfd_arm_pe_allocate_interworking_sections (& link_info);
#endif /* TARGET_IS_armpe */
+
+ if (!link_info.relocatable)
+ strip_excluded_output_sections ();
}
\f
#ifdef DLL_SUPPORT
hdyn->u.def.section = sdyn;
else
hdyn->u.def.section = bfd_abs_section_ptr;
+
+ strip_excluded_output_sections ();
}
}
/* ldemul.c -- clearing house for ld emulation states
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003
+ 2001, 2002, 2003, 2005
Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
#include "bfd.h"
#include "sysdep.h"
#include "getopt.h"
+#include "bfdlink.h"
#include "ld.h"
#include "ldmisc.h"
void
ldemul_before_allocation (void)
{
- if (ld_emulation->before_allocation)
- ld_emulation->before_allocation ();
+ ld_emulation->before_allocation ();
}
void
void
before_allocation_default (void)
{
+ if (!link_info.relocatable)
+ strip_excluded_output_sections ();
}
void
static const char *startup_file;
static lang_statement_list_type input_file_chain;
static bfd_boolean placed_commons = FALSE;
+static bfd_boolean stripped_excluded_sections = FALSE;
static lang_output_section_statement_type *default_common_section;
static bfd_boolean map_option_f;
static bfd_vma print_dot;
first = ! output->bfd_section->linker_has_input;
output->bfd_section->linker_has_input = 1;
+ if (!link_info.relocatable
+ && !stripped_excluded_sections)
+ {
+ asection *s = output->bfd_section->map_tail.s;
+ output->bfd_section->map_tail.s = section;
+ section->map_head.s = NULL;
+ section->map_tail.s = s;
+ if (s != NULL)
+ s->map_head.s = section;
+ else
+ output->bfd_section->map_head.s = section;
+ }
+
/* Add a section reference to the list. */
new = new_stat (lang_input_section, ptr);
added. For example, ldemul_before_allocation can remove dynamic
sections if they turn out to be not needed. Clean them up here. */
-static void
+void
strip_excluded_output_sections (void)
{
lang_output_section_statement_type *os;
if (os->constraint == -1)
continue;
- s = os->bfd_section;
- if (s != NULL && (s->flags & SEC_EXCLUDE) != 0)
+
+ if (os->bfd_section == NULL || os->bfd_section->map_head.s == NULL)
+ continue;
+
+ for (s = os->bfd_section->map_head.s; s != NULL; s = s->map_head.s)
+ if ((s->flags & SEC_EXCLUDE) == 0)
+ break;
+
+ os->bfd_section->map_head.link_order = NULL;
+ os->bfd_section->map_tail.link_order = NULL;
+
+ if (s == NULL)
{
+ s = os->bfd_section;
os->bfd_section = NULL;
if (!bfd_section_removed_from_list (output_bfd, s))
{
}
}
}
+
+ /* Stop future calls to lang_add_section from messing with map_head
+ and map_tail link_order fields. */
+ stripped_excluded_sections = TRUE;
}
static void
and other back-ends size dynamic sections. */
ldemul_before_allocation ();
- if (!link_info.relocatable)
- strip_excluded_output_sections ();
-
/* We must record the program headers before we try to fix the
section positions, since they will affect SIZEOF_HEADERS. */
lang_record_phdrs ();
(void (*) (lang_statement_union_type *));
extern void *stat_alloc
(size_t);
+extern void strip_excluded_output_sections
+ (void);
extern void dprint_statement
(lang_statement_union_type *, int);
extern bfd_vma lang_size_sections
static void
ds (asection *s)
{
- struct bfd_link_order *l = s->link_order_head;
+ struct bfd_link_order *l = s->map_head.link_order;
printf ("vma %x size %x\n", s->vma, s->size);
while (l)
{
{
struct bfd_link_order *p;
bfd_vma prev = 0;
- for (p = s->link_order_head; p; p = p->next)
+ for (p = s->map_head.link_order; p; p = p->next)
{
if (p->offset > 100000)
abort ();
/* Count up the relocations and line entries to see if anything
would be too big to fit. Accumulate section size too. */
- for (l = NULL, p = cursor->link_order_head; p != NULL; p = l->next)
+ for (l = NULL, p = cursor->map_head.link_order; p != NULL; p = l->next)
{
unsigned int thislines = 0;
unsigned int thisrelocs = 0;
/* Attach the link orders to the new section and snip
them off from the old section. */
- n->link_order_head = p;
- n->link_order_tail = cursor->link_order_tail;
- cursor->link_order_tail = l;
+ n->map_head.link_order = p;
+ n->map_tail.link_order = cursor->map_tail.link_order;
+ cursor->map_tail.link_order = l;
l->next = NULL;
l = p;