aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf.c
diff options
context:
space:
mode:
authorPaul Brook <paul@codesourcery.com>2004-11-15 23:21:27 +0000
committerPaul Brook <paul@codesourcery.com>2004-11-15 23:21:27 +0000
commitfc0e6df64dd2d64f16469008668ccea697291758 (patch)
tree49da66fa6655847c298d71374872aaa31a969aa3 /bfd/elf.c
parent2e8d14f48283a91dd8874ecaea037e904c047998 (diff)
downloadgdb-fc0e6df64dd2d64f16469008668ccea697291758.zip
gdb-fc0e6df64dd2d64f16469008668ccea697291758.tar.gz
gdb-fc0e6df64dd2d64f16469008668ccea697291758.tar.bz2
bfd/
* elf-bfd.h (_bfd_elf_slurp_version_tables): Update prototype. * elf.c (_bfd_elf_print_private_bfd_data): Pass extra argument. (_bfd_elf_slurp_version_tables): Add extra argument. Create extra default version definition for unversioned symbols. * elfcode.h (elf_slurp_symbol_table): Pass extra argument. * elflink.c (elf_link_add_object_symbols): Pass extra argument to _bfd_elf_slurp_version_tables. Set default version for unversioned imported symbols. include/ * bfdlink.h (bfd_link_info): Add default_imported_symver. ld/ * ld.texinfo: Document --default-imported-symver. * ldmain.c (main): Set link_info.default_imported_symver. * lexsup.c (option_values): Add OPTION_DEFAULT_IMPORTED_SYMVER. (ld_options): Add --default-imported-symver. (parse_args): Handle OPTION_DEFAULT_IMPORTED_SYMVER.
Diffstat (limited to 'bfd/elf.c')
-rw-r--r--bfd/elf.c194
1 files changed, 123 insertions, 71 deletions
diff --git a/bfd/elf.c b/bfd/elf.c
index a82387c..dcb5c3d 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1192,7 +1192,7 @@ _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
if ((elf_dynverdef (abfd) != 0 && elf_tdata (abfd)->verdef == NULL)
|| (elf_dynverref (abfd) != 0 && elf_tdata (abfd)->verref == NULL))
{
- if (! _bfd_elf_slurp_version_tables (abfd))
+ if (! _bfd_elf_slurp_version_tables (abfd, FALSE))
return FALSE;
}
@@ -6027,10 +6027,94 @@ _bfd_elf_canonicalize_dynamic_reloc (bfd *abfd,
/* Read in the version information. */
bfd_boolean
-_bfd_elf_slurp_version_tables (bfd *abfd)
+_bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
{
bfd_byte *contents = NULL;
bfd_size_type amt;
+ unsigned int freeidx = 0;
+
+ if (elf_dynverref (abfd) != 0)
+ {
+ Elf_Internal_Shdr *hdr;
+ Elf_External_Verneed *everneed;
+ Elf_Internal_Verneed *iverneed;
+ unsigned int i;
+
+ hdr = &elf_tdata (abfd)->dynverref_hdr;
+
+ amt = (bfd_size_type) hdr->sh_info * sizeof (Elf_Internal_Verneed);
+ elf_tdata (abfd)->verref = bfd_zalloc (abfd, amt);
+ if (elf_tdata (abfd)->verref == NULL)
+ goto error_return;
+
+ elf_tdata (abfd)->cverrefs = hdr->sh_info;
+
+ contents = bfd_malloc (hdr->sh_size);
+ if (contents == NULL)
+ goto error_return;
+ if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
+ || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
+ goto error_return;
+
+ everneed = (Elf_External_Verneed *) contents;
+ iverneed = elf_tdata (abfd)->verref;
+ for (i = 0; i < hdr->sh_info; i++, iverneed++)
+ {
+ Elf_External_Vernaux *evernaux;
+ Elf_Internal_Vernaux *ivernaux;
+ unsigned int j;
+
+ _bfd_elf_swap_verneed_in (abfd, everneed, iverneed);
+
+ iverneed->vn_bfd = abfd;
+
+ iverneed->vn_filename =
+ bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
+ iverneed->vn_file);
+ if (iverneed->vn_filename == NULL)
+ goto error_return;
+
+ amt = iverneed->vn_cnt;
+ amt *= sizeof (Elf_Internal_Vernaux);
+ iverneed->vn_auxptr = bfd_alloc (abfd, amt);
+
+ evernaux = ((Elf_External_Vernaux *)
+ ((bfd_byte *) everneed + iverneed->vn_aux));
+ ivernaux = iverneed->vn_auxptr;
+ for (j = 0; j < iverneed->vn_cnt; j++, ivernaux++)
+ {
+ _bfd_elf_swap_vernaux_in (abfd, evernaux, ivernaux);
+
+ ivernaux->vna_nodename =
+ bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
+ ivernaux->vna_name);
+ if (ivernaux->vna_nodename == NULL)
+ goto error_return;
+
+ if (j + 1 < iverneed->vn_cnt)
+ ivernaux->vna_nextptr = ivernaux + 1;
+ else
+ ivernaux->vna_nextptr = NULL;
+
+ evernaux = ((Elf_External_Vernaux *)
+ ((bfd_byte *) evernaux + ivernaux->vna_next));
+
+ if (ivernaux->vna_other > freeidx)
+ freeidx = ivernaux->vna_other;
+ }
+
+ if (i + 1 < hdr->sh_info)
+ iverneed->vn_nextref = iverneed + 1;
+ else
+ iverneed->vn_nextref = NULL;
+
+ everneed = ((Elf_External_Verneed *)
+ ((bfd_byte *) everneed + iverneed->vn_next));
+ }
+
+ free (contents);
+ contents = NULL;
+ }
if (elf_dynverdef (abfd) != 0)
{
@@ -6067,6 +6151,13 @@ _bfd_elf_slurp_version_tables (bfd *abfd)
((bfd_byte *) everdef + iverdefmem.vd_next));
}
+ if (default_imported_symver)
+ {
+ if (freeidx > maxidx)
+ maxidx = ++freeidx;
+ else
+ freeidx = ++maxidx;
+ }
amt = (bfd_size_type) maxidx * sizeof (Elf_Internal_Verdef);
elf_tdata (abfd)->verdef = bfd_zalloc (abfd, amt);
if (elf_tdata (abfd)->verdef == NULL)
@@ -6130,85 +6221,46 @@ _bfd_elf_slurp_version_tables (bfd *abfd)
free (contents);
contents = NULL;
}
-
- if (elf_dynverref (abfd) != 0)
+ else if (default_imported_symver)
{
- Elf_Internal_Shdr *hdr;
- Elf_External_Verneed *everneed;
- Elf_Internal_Verneed *iverneed;
- unsigned int i;
-
- hdr = &elf_tdata (abfd)->dynverref_hdr;
-
- amt = (bfd_size_type) hdr->sh_info * sizeof (Elf_Internal_Verneed);
- elf_tdata (abfd)->verref = bfd_zalloc (abfd, amt);
- if (elf_tdata (abfd)->verref == NULL)
- goto error_return;
-
- elf_tdata (abfd)->cverrefs = hdr->sh_info;
+ if (freeidx < 3)
+ freeidx = 3;
+ else
+ freeidx++;
- contents = bfd_malloc (hdr->sh_size);
- if (contents == NULL)
- goto error_return;
- if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
+ amt = (bfd_size_type) freeidx * sizeof (Elf_Internal_Verdef);
+ elf_tdata (abfd)->verdef = bfd_zalloc (abfd, amt);
+ if (elf_tdata (abfd)->verdef == NULL)
goto error_return;
- everneed = (Elf_External_Verneed *) contents;
- iverneed = elf_tdata (abfd)->verref;
- for (i = 0; i < hdr->sh_info; i++, iverneed++)
- {
- Elf_External_Vernaux *evernaux;
- Elf_Internal_Vernaux *ivernaux;
- unsigned int j;
-
- _bfd_elf_swap_verneed_in (abfd, everneed, iverneed);
-
- iverneed->vn_bfd = abfd;
-
- iverneed->vn_filename =
- bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
- iverneed->vn_file);
- if (iverneed->vn_filename == NULL)
- goto error_return;
-
- amt = iverneed->vn_cnt;
- amt *= sizeof (Elf_Internal_Vernaux);
- iverneed->vn_auxptr = bfd_alloc (abfd, amt);
-
- evernaux = ((Elf_External_Vernaux *)
- ((bfd_byte *) everneed + iverneed->vn_aux));
- ivernaux = iverneed->vn_auxptr;
- for (j = 0; j < iverneed->vn_cnt; j++, ivernaux++)
- {
- _bfd_elf_swap_vernaux_in (abfd, evernaux, ivernaux);
+ elf_tdata (abfd)->cverdefs = freeidx;
+ }
- ivernaux->vna_nodename =
- bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
- ivernaux->vna_name);
- if (ivernaux->vna_nodename == NULL)
- goto error_return;
+ /* Create a default version based on the soname. */
+ if (default_imported_symver)
+ {
+ Elf_Internal_Verdef *iverdef;
+ Elf_Internal_Verdaux *iverdaux;
- if (j + 1 < iverneed->vn_cnt)
- ivernaux->vna_nextptr = ivernaux + 1;
- else
- ivernaux->vna_nextptr = NULL;
+ iverdef = &elf_tdata (abfd)->verdef[freeidx - 1];;
- evernaux = ((Elf_External_Vernaux *)
- ((bfd_byte *) evernaux + ivernaux->vna_next));
- }
+ iverdef->vd_version = VER_DEF_CURRENT;
+ iverdef->vd_flags = 0;
+ iverdef->vd_ndx = freeidx;
+ iverdef->vd_cnt = 1;
- if (i + 1 < hdr->sh_info)
- iverneed->vn_nextref = iverneed + 1;
- else
- iverneed->vn_nextref = NULL;
+ iverdef->vd_bfd = abfd;
- everneed = ((Elf_External_Verneed *)
- ((bfd_byte *) everneed + iverneed->vn_next));
- }
+ iverdef->vd_nodename = bfd_elf_get_dt_soname (abfd);
+ if (iverdef->vd_nodename == NULL)
+ goto error_return;
+ iverdef->vd_nextdef = NULL;
+ amt = (bfd_size_type) sizeof (Elf_Internal_Verdaux);
+ iverdef->vd_auxptr = bfd_alloc (abfd, amt);
- free (contents);
- contents = NULL;
+ iverdaux = iverdef->vd_auxptr;
+ iverdaux->vda_nodename = iverdef->vd_nodename;
+ iverdaux->vda_nextptr = NULL;
}
return TRUE;