aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-06-13 14:49:51 +0000
committerMark Mitchell <mark@codesourcery.com>1999-06-13 14:49:51 +0000
commit42751cf354f999d77243bdf2171602bfc08fce5f (patch)
tree277f587d1e8b40bde923a2d63872d23a93ee4adb /bfd
parent5076851fbc4405863b3552011b67d04f364d7eb4 (diff)
downloadgdb-42751cf354f999d77243bdf2171602bfc08fce5f.zip
gdb-42751cf354f999d77243bdf2171602bfc08fce5f.tar.gz
gdb-42751cf354f999d77243bdf2171602bfc08fce5f.tar.bz2
* 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.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog8
-rw-r--r--bfd/elf-bfd.h2
-rw-r--r--bfd/elflink.c15
-rw-r--r--bfd/elflink.h92
4 files changed, 83 insertions, 34 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index c0d45a5..e75acf0 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index d004219..49c5eae 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -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,
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 829d977..d644e1b 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -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 */
diff --git a/bfd/elflink.h b/bfd/elflink.h
index fcbacf8..88fd05c 100644
--- a/bfd/elflink.h
+++ b/bfd/elflink.h
@@ -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
{