|
|
|
@ -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; |
|
|
|
|