diff options
author | Paul Brook <paul@codesourcery.com> | 2004-11-15 23:21:27 +0000 |
---|---|---|
committer | Paul Brook <paul@codesourcery.com> | 2004-11-15 23:21:27 +0000 |
commit | fc0e6df64dd2d64f16469008668ccea697291758 (patch) | |
tree | 49da66fa6655847c298d71374872aaa31a969aa3 /bfd/elf.c | |
parent | 2e8d14f48283a91dd8874ecaea037e904c047998 (diff) | |
download | gdb-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.c | 194 |
1 files changed, 123 insertions, 71 deletions
@@ -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; |