aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2004-05-25 06:33:51 +0000
committerAlan Modra <amodra@gmail.com>2004-05-25 06:33:51 +0000
commit57ceae9483c03910f7ee7ac66f3cb118c9d7d657 (patch)
treea5653edf9e28f48685a159531cb5d8dc82fedda5 /bfd
parent81bb3443544bff4a3cc386acc5d4f1a6339967da (diff)
downloadgdb-57ceae9483c03910f7ee7ac66f3cb118c9d7d657.zip
gdb-57ceae9483c03910f7ee7ac66f3cb118c9d7d657.tar.gz
gdb-57ceae9483c03910f7ee7ac66f3cb118c9d7d657.tar.bz2
bfd/
* elflink.c (elf_link_add_object_symbols): Don't set up merge section data here.. * elf.c (_bfd_elf_merge_sections): .. Do it here instead. * merge.c: Formatting. Remove unnecessary casts. Expand bfd_get_section_alignment macro. (struct sec_merge_sec_info): Rename "first" to "first_str". Update use throughout file. (_bfd_add_merge_section): Rename from _bfd_merge_section. Update comment. Abort on dynamic or non-SEC_MERGE input. Don't test section name to determine sinfo group, instead test output section and alignment. (_bfd_merge_sections): Add struct bfd_link_info param. Call _bfd_strip_section_from_output rather than just twiddling flags. * libbfd-in.h (_bfd_add_merge_section): Rename, update comment. (_bfd_merge_sections): Update prototype. * libbfd.h: Regenerate. ld/ * ldlang.c (lang_process): Call bfd_merge_sections later, and only when not a relocatable link. (print_input_section): Handle SEC_EXCLUDE sections. (size_input_section): Don't update dot on SEC_EXCLUDE sections. (lang_do_assignments_1): Likewise. * ldwrite.c (build_link_order): Ignore SEC_EXCLUDE input sections. * emultempl/armelf.em (arm_elf_set_bfd_for_interworking): Likewise. * emultempl/hppaelf.em (build_section_lists): Likewise. * emultempl/ppc64elf.em (build_toc_list): Likewise. (build_section_lists): Likewise.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog19
-rw-r--r--bfd/elf.c25
-rw-r--r--bfd/elflink.c22
-rw-r--r--bfd/libbfd-in.h6
-rw-r--r--bfd/libbfd.h6
-rw-r--r--bfd/merge.c105
6 files changed, 99 insertions, 84 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index dab90b4..93ae1f6 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,22 @@
+2004-05-25 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_link_add_object_symbols): Don't set up merge
+ section data here..
+ * elf.c (_bfd_elf_merge_sections): .. Do it here instead.
+ * merge.c: Formatting. Remove unnecessary casts. Expand
+ bfd_get_section_alignment macro.
+ (struct sec_merge_sec_info): Rename "first" to "first_str". Update
+ use throughout file.
+ (_bfd_add_merge_section): Rename from _bfd_merge_section. Update
+ comment. Abort on dynamic or non-SEC_MERGE input. Don't test
+ section name to determine sinfo group, instead test output section
+ and alignment.
+ (_bfd_merge_sections): Add struct bfd_link_info param. Call
+ _bfd_strip_section_from_output rather than just twiddling flags.
+ * libbfd-in.h (_bfd_add_merge_section): Rename, update comment.
+ (_bfd_merge_sections): Update prototype.
+ * libbfd.h: Regenerate.
+
2004-05-24 Mark Kettenis <kettenis@gnu.org>
* netbsd-core.c: Correctly indent section that sets architecture
diff --git a/bfd/elf.c b/bfd/elf.c
index e5ab09e..93a3d3a 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -901,10 +901,31 @@ merge_sections_remove_hook (bfd *abfd ATTRIBUTE_UNUSED,
bfd_boolean
_bfd_elf_merge_sections (bfd *abfd, struct bfd_link_info *info)
{
+ bfd *ibfd;
+ asection *sec;
+
if (!is_elf_hash_table (info->hash))
return FALSE;
- if (elf_hash_table (info)->merge_info)
- _bfd_merge_sections (abfd, elf_hash_table (info)->merge_info,
+
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+ if ((ibfd->flags & DYNAMIC) == 0)
+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+ if ((sec->flags & SEC_MERGE) != 0
+ && !bfd_is_abs_section (sec->output_section))
+ {
+ struct bfd_elf_section_data *secdata;
+
+ secdata = elf_section_data (sec);
+ if (! _bfd_add_merge_section (abfd,
+ &elf_hash_table (info)->merge_info,
+ sec, &secdata->sec_info))
+ return FALSE;
+ else if (secdata->sec_info)
+ sec->sec_info_type = ELF_INFO_TYPE_MERGE;
+ }
+
+ if (elf_hash_table (info)->merge_info != NULL)
+ _bfd_merge_sections (abfd, info, elf_hash_table (info)->merge_info,
merge_sections_remove_hook);
return TRUE;
}
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 37540aa..436ff84 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -4127,28 +4127,6 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
}
}
- if (! info->relocatable
- && ! dynamic
- && is_elf_hash_table (hash_table))
- {
- asection *s;
-
- for (s = abfd->sections; s != NULL; s = s->next)
- if ((s->flags & SEC_MERGE) != 0
- && !bfd_is_abs_section (s->output_section))
- {
- struct bfd_elf_section_data *secdata;
-
- secdata = elf_section_data (s);
- if (! _bfd_merge_section (abfd,
- & hash_table->merge_info,
- s, &secdata->sec_info))
- goto error_return;
- else if (secdata->sec_info)
- s->sec_info_type = ELF_INFO_TYPE_MERGE;
- }
- }
-
if (is_elf_hash_table (hash_table))
{
/* Add this bfd to the loaded list. */
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index 956727d..fd7f296 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -520,15 +520,15 @@ extern bfd_boolean _bfd_write_stab_strings
extern bfd_vma _bfd_stab_section_offset
(bfd *, void **, asection *, void **, bfd_vma);
-/* Attempt to merge a SEC_MERGE section. */
+/* Register a SEC_MERGE section as a candidate for merging. */
-extern bfd_boolean _bfd_merge_section
+extern bfd_boolean _bfd_add_merge_section
(bfd *, void **, asection *, void **);
/* Attempt to merge SEC_MERGE sections. */
extern bfd_boolean _bfd_merge_sections
- (bfd *, void *, void (*) (bfd *, asection *));
+ (bfd *, struct bfd_link_info *, void *, void (*) (bfd *, asection *));
/* Write out a merged section. */
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 96776ca..30890bc 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -525,15 +525,15 @@ extern bfd_boolean _bfd_write_stab_strings
extern bfd_vma _bfd_stab_section_offset
(bfd *, void **, asection *, void **, bfd_vma);
-/* Attempt to merge a SEC_MERGE section. */
+/* Register a SEC_MERGE section as a candidate for merging. */
-extern bfd_boolean _bfd_merge_section
+extern bfd_boolean _bfd_add_merge_section
(bfd *, void **, asection *, void **);
/* Attempt to merge SEC_MERGE sections. */
extern bfd_boolean _bfd_merge_sections
- (bfd *, void *, void (*) (bfd *, asection *));
+ (bfd *, struct bfd_link_info *, void *, void (*) (bfd *, asection *));
/* Write out a merged section. */
diff --git a/bfd/merge.c b/bfd/merge.c
index 3811523..6b367b5 100644
--- a/bfd/merge.c
+++ b/bfd/merge.c
@@ -90,7 +90,7 @@ struct sec_merge_sec_info
/* A hash table used to hold section content. */
struct sec_merge_hash *htab;
/* First string in this section. */
- struct sec_merge_hash_entry *first;
+ struct sec_merge_hash_entry *first_str;
/* Original section content. */
unsigned char contents[1];
};
@@ -102,30 +102,28 @@ static struct bfd_hash_entry *
sec_merge_hash_newfunc (struct bfd_hash_entry *entry,
struct bfd_hash_table *table, const char *string)
{
- struct sec_merge_hash_entry *ret = (struct sec_merge_hash_entry *) entry;
-
/* Allocate the structure if it has not already been allocated by a
subclass. */
- if (ret == (struct sec_merge_hash_entry *) NULL)
- ret = ((struct sec_merge_hash_entry *)
- bfd_hash_allocate (table, sizeof (struct sec_merge_hash_entry)));
- if (ret == (struct sec_merge_hash_entry *) NULL)
+ if (entry == NULL)
+ entry = bfd_hash_allocate (table, sizeof (struct sec_merge_hash_entry));
+ if (entry == NULL)
return NULL;
/* Call the allocation method of the superclass. */
- ret = ((struct sec_merge_hash_entry *)
- bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
+ entry = bfd_hash_newfunc (entry, table, string);
- if (ret)
+ if (entry != NULL)
{
/* Initialize the local fields. */
+ struct sec_merge_hash_entry *ret = (struct sec_merge_hash_entry *) entry;
+
ret->u.suffix = NULL;
ret->alignment = 0;
ret->secinfo = NULL;
ret->next = NULL;
}
- return (struct bfd_hash_entry *) ret;
+ return entry;
}
/* Look up an entry in a section merge hash table. */
@@ -192,7 +190,7 @@ sec_merge_hash_lookup (struct sec_merge_hash *table, const char *string,
index = hash % table->table.size;
for (hashp = (struct sec_merge_hash_entry *) table->table.table[index];
- hashp != (struct sec_merge_hash_entry *) NULL;
+ hashp != NULL;
hashp = (struct sec_merge_hash_entry *) hashp->root.next)
{
if (hashp->root.hash == hash
@@ -216,13 +214,12 @@ sec_merge_hash_lookup (struct sec_merge_hash *table, const char *string,
}
if (! create)
- return (struct sec_merge_hash_entry *) NULL;
+ return NULL;
- hashp = (struct sec_merge_hash_entry *)
- sec_merge_hash_newfunc ((struct bfd_hash_entry *) NULL,
- (struct bfd_hash_table *) table, string);
- if (hashp == (struct sec_merge_hash_entry *) NULL)
- return (struct sec_merge_hash_entry *) NULL;
+ hashp = ((struct sec_merge_hash_entry *)
+ sec_merge_hash_newfunc (NULL, &table->table, string));
+ if (hashp == NULL)
+ return NULL;
hashp->root.string = string;
hashp->root.hash = hash;
hashp->len = len;
@@ -239,9 +236,8 @@ static struct sec_merge_hash *
sec_merge_init (unsigned int entsize, bfd_boolean strings)
{
struct sec_merge_hash *table;
- bfd_size_type amt = sizeof (struct sec_merge_hash);
- table = (struct sec_merge_hash *) bfd_malloc (amt);
+ table = bfd_malloc (sizeof (struct sec_merge_hash));
if (table == NULL)
return NULL;
@@ -294,7 +290,7 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
asection *sec = secinfo->sec;
char *pad = "";
bfd_size_type off = 0;
- int alignment_power = bfd_get_section_alignment (abfd, sec->output_section);
+ int alignment_power = sec->output_section->alignment_power;
if (alignment_power)
pad = bfd_zmalloc ((bfd_size_type) 1 << alignment_power);
@@ -308,7 +304,7 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
if (len)
{
len = entry->alignment - len;
- if (bfd_bwrite (pad, (bfd_size_type) len, abfd) != len)
+ if (bfd_bwrite (pad, len, abfd) != len)
break;
off += len;
}
@@ -316,7 +312,7 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
str = entry->root.string;
len = entry->len;
- if (bfd_bwrite (str, (bfd_size_type) len, abfd) != len)
+ if (bfd_bwrite (str, len, abfd) != len)
break;
off += len;
@@ -328,20 +324,24 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
return entry == NULL || entry->secinfo != secinfo;
}
-/* This function is called for each input file from the add_symbols
- pass of the linker. */
+/* Register a SEC_MERGE section as a candidate for merging.
+ This function is called for all non-dynamic SEC_MERGE input sections. */
bfd_boolean
-_bfd_merge_section (bfd *abfd, void **psinfo, asection *sec, void **psecinfo)
+_bfd_add_merge_section (bfd *abfd, void **psinfo, asection *sec,
+ void **psecinfo)
{
struct sec_merge_info *sinfo;
struct sec_merge_sec_info *secinfo;
unsigned int align;
bfd_size_type amt;
+ if ((abfd->flags & DYNAMIC) != 0
+ || (sec->flags & SEC_MERGE) == 0)
+ abort ();
+
if (sec->_raw_size == 0
- || (sec->flags & SEC_EXCLUDE)
- || (sec->flags & SEC_MERGE) == 0
+ || (sec->flags & SEC_EXCLUDE) != 0
|| sec->entsize == 0)
return TRUE;
@@ -351,12 +351,12 @@ _bfd_merge_section (bfd *abfd, void **psinfo, asection *sec, void **psecinfo)
return TRUE;
}
- align = bfd_get_section_alignment (sec->owner, sec);
- if ((sec->entsize < (unsigned int)(1 << align)
+ align = sec->alignment_power;
+ if ((sec->entsize < (unsigned) 1 << align
&& ((sec->entsize & (sec->entsize - 1))
|| !(sec->flags & SEC_STRINGS)))
- || (sec->entsize > (unsigned int)(1 << align)
- && (sec->entsize & ((1 << align) - 1))))
+ || (sec->entsize > (unsigned) 1 << align
+ && (sec->entsize & (((unsigned) 1 << align) - 1))))
{
/* Sanity check. If string character size is smaller than
alignment, then we require character size to be a power
@@ -371,14 +371,14 @@ _bfd_merge_section (bfd *abfd, void **psinfo, asection *sec, void **psecinfo)
if ((secinfo = sinfo->chain)
&& ! ((secinfo->sec->flags ^ sec->flags) & (SEC_MERGE | SEC_STRINGS))
&& secinfo->sec->entsize == sec->entsize
- && ! strcmp (secinfo->sec->name, sec->name))
+ && secinfo->sec->alignment_power == sec->alignment_power
+ && secinfo->sec->output_section == sec->output_section)
break;
if (sinfo == NULL)
{
/* Initialize the information we need to keep track of. */
- amt = sizeof (struct sec_merge_info);
- sinfo = (struct sec_merge_info *) bfd_alloc (abfd, amt);
+ sinfo = bfd_alloc (abfd, sizeof (struct sec_merge_info));
if (sinfo == NULL)
goto error_return;
sinfo->next = (struct sec_merge_info *) *psinfo;
@@ -396,7 +396,7 @@ _bfd_merge_section (bfd *abfd, void **psinfo, asection *sec, void **psecinfo)
if (*psecinfo == NULL)
goto error_return;
- secinfo = (struct sec_merge_sec_info *)*psecinfo;
+ secinfo = (struct sec_merge_sec_info *) *psecinfo;
if (sinfo->chain)
{
secinfo->next = sinfo->chain->next;
@@ -408,10 +408,10 @@ _bfd_merge_section (bfd *abfd, void **psinfo, asection *sec, void **psecinfo)
secinfo->sec = sec;
secinfo->psecinfo = psecinfo;
secinfo->htab = sinfo->htab;
- secinfo->first = NULL;
+ secinfo->first_str = NULL;
if (! bfd_get_section_contents (sec->owner, sec, secinfo->contents,
- (bfd_vma) 0, sec->_raw_size))
+ 0, sec->_raw_size))
goto error_return;
return TRUE;
@@ -433,7 +433,7 @@ record_section (struct sec_merge_info *sinfo,
bfd_vma mask, eltalign;
unsigned int align, i;
- align = bfd_get_section_alignment (sec->owner, sec);
+ align = sec->alignment_power;
end = secinfo->contents + sec->_raw_size;
nul = FALSE;
mask = ((bfd_vma) 1 << align) - 1;
@@ -580,7 +580,7 @@ merge_strings (struct sec_merge_info *sinfo)
/* Now sort the strings */
amt = sinfo->htab->size * sizeof (struct sec_merge_hash_entry *);
- array = (struct sec_merge_hash_entry **) bfd_malloc (amt);
+ array = bfd_malloc (amt);
if (array == NULL)
goto alloc_failure;
@@ -643,9 +643,9 @@ alloc_failure:
}
if (e->alignment)
{
- if (e->secinfo->first == NULL)
+ if (e->secinfo->first_str == NULL)
{
- e->secinfo->first = e;
+ e->secinfo->first_str = e;
size = 0;
}
size = (size + e->alignment - 1) & ~((bfd_vma) e->alignment - 1);
@@ -676,8 +676,8 @@ alloc_failure:
with _bfd_merge_section. */
bfd_boolean
-_bfd_merge_sections (bfd *abfd ATTRIBUTE_UNUSED, void *xsinfo,
- void (*remove_hook) (bfd *, asection *))
+_bfd_merge_sections (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info,
+ void *xsinfo, void (*remove_hook) (bfd *, asection *))
{
struct sec_merge_info *sinfo;
@@ -722,11 +722,11 @@ _bfd_merge_sections (bfd *abfd ATTRIBUTE_UNUSED, void *xsinfo,
secinfo = NULL;
for (e = sinfo->htab->first; e; e = e->next)
{
- if (e->secinfo->first == NULL)
+ if (e->secinfo->first_str == NULL)
{
if (secinfo)
secinfo->sec->_cooked_size = size;
- e->secinfo->first = e;
+ e->secinfo->first_str = e;
size = 0;
}
size = (size + e->alignment - 1)
@@ -741,11 +741,8 @@ _bfd_merge_sections (bfd *abfd ATTRIBUTE_UNUSED, void *xsinfo,
/* Finally remove all input sections which have not made it into
the hash table at all. */
for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
- if (secinfo->first == NULL)
- {
- secinfo->sec->_cooked_size = 0;
- secinfo->sec->flags |= SEC_EXCLUDE;
- }
+ if (secinfo->first_str == NULL)
+ _bfd_strip_section_from_output (info, secinfo->sec);
}
return TRUE;
@@ -761,14 +758,14 @@ _bfd_write_merged_section (bfd *output_bfd, asection *sec, void *psecinfo)
secinfo = (struct sec_merge_sec_info *) psecinfo;
- if (!secinfo->first)
+ if (secinfo->first_str == NULL)
return TRUE;
pos = sec->output_section->filepos + sec->output_offset;
if (bfd_seek (output_bfd, pos, SEEK_SET) != 0)
return FALSE;
- if (! sec_merge_emit (output_bfd, secinfo->first))
+ if (! sec_merge_emit (output_bfd, secinfo->first_str))
return FALSE;
return TRUE;
@@ -797,7 +794,7 @@ _bfd_merged_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, asection **psec,
(_("%s: access beyond end of merged section (%ld)"),
bfd_get_filename (sec->owner), (long) offset);
}
- return (secinfo->first ? sec->_cooked_size : 0);
+ return (secinfo->first_str ? sec->_cooked_size : 0);
}
if (secinfo->htab->strings)