* elf-bfd.h (_bfd_elf_link_adjust_dynindx): New function.

* elflink.c (_bfd_elf_link_adjust_dynindx): Define it.
	* elflink.h (elf_link_remove_section_and_adjust_dynindices): New
	function.
	(bfd_elf_size_dynamic_sections): Use it.
This commit is contained in:
Mark Mitchell 1999-06-13 14:49:51 +00:00
parent 5076851fbc
commit 42751cf354
4 changed files with 83 additions and 34 deletions

View File

@ -1,3 +1,11 @@
1999-06-13 Mark Mitchell <mark@codesourcery.com>
* elf-bfd.h (_bfd_elf_link_adjust_dynindx): New function.
* elflink.c (_bfd_elf_link_adjust_dynindx): Define it.
* elflink.h (elf_link_remove_section_and_adjust_dynindices): New
function.
(bfd_elf_size_dynamic_sections): Use it.
1999-06-13 Alan Modra <alan@spri.levels.unisa.edu.au>
* elf32-i386.c (elf_howto_table): Change R_386_PC8 from

View File

@ -927,6 +927,8 @@ boolean _bfd_elf_create_dynamic_sections PARAMS ((bfd *,
struct bfd_link_info *));
boolean _bfd_elf_create_got_section PARAMS ((bfd *,
struct bfd_link_info *));
boolean _bfd_elf_link_adjust_dynindx PARAMS ((struct elf_link_hash_entry *,
PTR));
elf_linker_section_t *_bfd_elf_create_linker_section
PARAMS ((bfd *abfd,

View File

@ -259,6 +259,21 @@ _bfd_elf_link_record_dynamic_symbol (info, h)
return true;
}
/* Increase the index at which H will appear in the dynamic symbol
table by INCREMENT (which is really an `int *'). Called via
elf_link_hash_traverse. */
boolean
_bfd_elf_link_adjust_dynindx (h, increment)
struct elf_link_hash_entry *h;
PTR increment;
{
if (h->dynindx != -1)
h->dynindx += *((int *) increment);
return true;
}
/* Create a special linker section, or return a pointer to a linker section already created */

View File

@ -54,6 +54,8 @@ static boolean elf_collect_hash_codes
PARAMS ((struct elf_link_hash_entry *, PTR));
static boolean elf_link_read_relocs_from_section
PARAMS ((bfd *, Elf_Internal_Shdr *, PTR, Elf_Internal_Rela *));
static void elf_link_remove_section_and_adjust_dynindices
PARAMS ((bfd *, struct bfd_link_info *, asection *));
/* Given an ELF BFD, add symbols to the global hash table as
appropriate. */
@ -2401,6 +2403,50 @@ compute_bucket_count (info)
return best_size;
}
/* Remove SECTION from the BFD. If a symbol for SECTION was going to
be put into the dynamic symbol table, remove it, and renumber
subsequent entries. */
static void
elf_link_remove_section_and_adjust_dynindices (abfd, info, section)
bfd *abfd;
struct bfd_link_info *info;
asection *section;
{
asection **spp;
/* Remove the section from the output list. */
for (spp = &abfd->sections;
*spp != section->output_section;
spp = &(*spp)->next)
;
*spp = section->output_section->next;
--abfd->section_count;
if (elf_section_data (section->output_section)->dynindx)
{
asection *s;
int increment = -1;
/* We were going to output an entry in the dynamic symbol table
for the symbol corresponding to this section. Now, the
section is gone. So, we must renumber the dynamic indices of
all subsequent sections and all other entries in the dynamic
symbol table. */
elf_section_data (section->output_section)->dynindx = 0;
for (s = section->output_section->next; s; s = s->next)
if (elf_section_data (s)->dynindx)
--elf_section_data (s)->dynindx;
elf_link_hash_traverse (elf_hash_table (info),
_bfd_elf_link_adjust_dynindx,
&increment);
/* There is one less dynamic symbol than there was before. */
--elf_hash_table (info)->dynsymcount;
}
}
/* Set up the sizes and contents of the ELF dynamic sections. This is
called by the ELF linker emulation before_allocation routine. We
must set the sizes of the sections before the linker sets the
@ -2602,17 +2648,9 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
verdefs = asvinfo.verdefs;
if (verdefs == NULL)
{
asection **spp;
/* Don't include this section in the output file. */
for (spp = &output_bfd->sections;
*spp != s->output_section;
spp = &(*spp)->next)
;
*spp = s->output_section->next;
--output_bfd->section_count;
}
elf_link_remove_section_and_adjust_dynindices (output_bfd,
info,
s);
else
{
unsigned int cdefs;
@ -2805,19 +2843,9 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
(PTR) &sinfo);
if (elf_tdata (output_bfd)->verref == NULL)
{
asection **spp;
/* We don't have any version definitions, so we can just
remove the section. */
for (spp = &output_bfd->sections;
*spp != s->output_section;
spp = &(*spp)->next)
;
*spp = s->output_section->next;
--output_bfd->section_count;
}
elf_link_remove_section_and_adjust_dynindices (output_bfd,
info,
s);
else
{
Elf_Internal_Verneed *t;
@ -2917,16 +2945,12 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
if (dynsymcount == 0
|| (verdefs == NULL && elf_tdata (output_bfd)->verref == NULL))
{
asection **spp;
/* We don't need any symbol versions; just discard the
section. */
for (spp = &output_bfd->sections;
*spp != s->output_section;
spp = &(*spp)->next)
;
*spp = s->output_section->next;
--output_bfd->section_count;
elf_link_remove_section_and_adjust_dynindices (output_bfd,
info,
s);
/* The DYNSYMCOUNT might have changed if we were going to
output a dynamic symbol table entry for S. */
dynsymcount = elf_hash_table (info)->dynsymcount;
}
else
{