summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-08-10 03:36:28 +0000
committerMark Mitchell <mark@codesourcery.com>1999-08-10 03:36:28 +0000
commit5444e5dd114f1f2b8098c88bdb76a7686af56856 (patch)
tree1b6040bb74aa7ca496ad3a2f5f93695161ad4996
parentc6676ba824b2dbb69bf9d07cc3f06a9af228239c (diff)
downloadgdb-5444e5dd114f1f2b8098c88bdb76a7686af56856.tar.gz
* elflink.h (elf_link_size_reloc_section): Use the counts in the
elf-section data to allocate just the right amount of relocation space. Don't allocate the hash space twice. (elf_bfd_final_link): Calculate the amount of space to allocate in each relocation section.
-rw-r--r--bfd/ChangeLog10
-rw-r--r--bfd/elflink.h76
2 files changed, 65 insertions, 21 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 00206124f04..a01598c2156 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,11 @@
+1999-08-09 Mark Mitchell <mark@codesourcery.com>
+
+ * elflink.h (elf_link_size_reloc_section): Use the counts in the
+ elf-section data to allocate just the right amount of relocation
+ space. Don't allocate the hash space twice.
+ (elf_bfd_final_link): Calculate the amount of space to allocate in
+ each relocation section.
+
Mon Aug 9 17:37:30 1999 Jeffrey A Law (law@cygnus.com)
* elf-hppa.h (_bfd_elf_hppa_gen_reloc_type, case 32): When in
@@ -12,7 +20,7 @@ Mon Aug 9 17:37:30 1999 Jeffrey A Law (law@cygnus.com)
* elf32-mips.c (elf_mips_howto_table): Fix src_mask for
R_MIPS_GOT16 and R_MIPS_CALL16.
(mips_elf_got16_entry): Use mips_elf_high to calculate the value
- to use wheen looking for a preexisting GOT entry.
+ to use when looking for a preexisting GOT entry.
1999-08-09 Jakub Jelinek <jj@ultra.linux.cz>
diff --git a/bfd/elflink.h b/bfd/elflink.h
index 60de241ad09..7bd95d44786 100644
--- a/bfd/elflink.h
+++ b/bfd/elflink.h
@@ -3761,34 +3761,38 @@ elf_link_size_reloc_section (abfd, rel_hdr, o)
asection *o;
{
register struct elf_link_hash_entry **p, **pend;
+ unsigned reloc_count;
- /* We are overestimating the size required for the relocation
- sections, in the case that we are using both REL and RELA
- relocations for a single section. In that case, RELOC_COUNT will
- be the total number of relocations required, and we allocate
- space for that many REL relocations as well as that many RELA
- relocations. This approximation is wasteful of disk space.
- However, until we keep track of how many of each kind of
- relocation is required, it's difficult to calculate the right
- value. */
- rel_hdr->sh_size = rel_hdr->sh_entsize * o->reloc_count;
+ /* Figure out how many relocations there will be. */
+ if (rel_hdr == &elf_section_data (o)->rel_hdr)
+ reloc_count = elf_section_data (o)->rel_count;
+ else
+ reloc_count = elf_section_data (o)->rel_count2;
+
+ /* That allows us to calculate the size of the section. */
+ rel_hdr->sh_size = rel_hdr->sh_entsize * reloc_count;
/* The contents field must last into write_object_contents, so we
allocate it with bfd_alloc rather than malloc. */
rel_hdr->contents = (PTR) bfd_alloc (abfd, rel_hdr->sh_size);
if (rel_hdr->contents == NULL && rel_hdr->sh_size != 0)
return false;
+
+ /* We only allocate one set of hash entries, so we only do it the
+ first time we are called. */
+ if (elf_section_data (o)->rel_hashes == NULL)
+ {
+ p = ((struct elf_link_hash_entry **)
+ bfd_malloc (o->reloc_count
+ * sizeof (struct elf_link_hash_entry *)));
+ if (p == NULL && o->reloc_count != 0)
+ return false;
- p = ((struct elf_link_hash_entry **)
- bfd_malloc (o->reloc_count
- * sizeof (struct elf_link_hash_entry *)));
- if (p == NULL && o->reloc_count != 0)
- return false;
-
- elf_section_data (o)->rel_hashes = p;
- pend = p + o->reloc_count;
- for (; p < pend; p++)
- *p = NULL;
+ elf_section_data (o)->rel_hashes = p;
+ pend = p + o->reloc_count;
+ for (; p < pend; p++)
+ *p = NULL;
+ }
return true;
}
@@ -3997,6 +4001,30 @@ elf_bfd_final_link (abfd, info)
if (! _bfd_elf_compute_section_file_positions (abfd, info))
goto error_return;
+ /* Figure out how many relocations we will have in each section.
+ Just using RELOC_COUNT isn't good enough since that doesn't
+ maintain a separate value for REL vs. RELA relocations. */
+ if (info->relocateable)
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ for (o = sub->sections; o != NULL; o = o->next)
+ {
+ asection* output_section = o->output_section;
+
+ if (output_section && (o->flags & SEC_RELOC) != 0)
+ {
+ struct bfd_elf_section_data *esdi
+ = elf_section_data (o);
+ struct bfd_elf_section_data *esdo
+ = elf_section_data (output_section);
+
+ esdo->rel_count += (esdi->rel_hdr.sh_size
+ / esdi->rel_hdr.sh_entsize);
+ if (esdi->rel_hdr2)
+ esdo->rel_count2 += (esdi->rel_hdr2->sh_size
+ / esdi->rel_hdr2->sh_entsize);
+ }
+ }
+
/* That created the reloc sections. Set their sizes, and assign
them file positions, and allocate some buffers. */
for (o = abfd->sections; o != NULL; o = o->next)
@@ -4014,6 +4042,11 @@ elf_bfd_final_link (abfd, info)
o))
goto error_return;
}
+
+ /* Now, reset REL_COUNT and REL_COUNT2 so that we can use them
+ to count upwards while actually outputting the relocations. */
+ elf_section_data (o)->rel_count = 0;
+ elf_section_data (o)->rel_count2 = 0;
}
_bfd_elf_assign_file_positions_for_relocs (abfd);
@@ -4250,6 +4283,9 @@ elf_bfd_final_link (abfd, info)
{
asection *s;
+ sym.st_size = e->isym.st_size;
+ sym.st_other = e->isym.st_other;
+
/* Copy the internal symbol as is.
Note that we saved a word of storage and overwrote
the original st_name with the dynstr_index. */