2000-07-19 H.J. Lu <hjl@gnu.org>

* bfd-in.h (bfd_elf_set_dt_needed_soname): New.
	* bfd-in2.h: Rebuild.

	* elf-bfd.h (elf_obj_tdata): Add dt_soname.
	(elf_dt_soname): New.

	* elf.c (bfd_elf_set_dt_needed_soname): New.

	* elflink.h (elf_link_add_object_symbols): Add the DT_NEEDED
	entry if the shared object loaded by DT_NEEDED is used to
	resolve the reference in a regular object.
This commit is contained in:
H.J. Lu
2000-07-20 03:16:18 +00:00
parent 019148e439
commit 7481689898
6 changed files with 91 additions and 1 deletions

View File

@@ -890,6 +890,7 @@ elf_link_add_object_symbols (abfd, info)
Elf_External_Sym *esym;
Elf_External_Sym *esymend;
struct elf_backend_data *bed;
boolean dt_needed;
bed = get_elf_backend_data (abfd);
add_symbol_hook = bed->elf_add_symbol_hook;
@@ -1049,6 +1050,8 @@ elf_link_add_object_symbols (abfd, info)
goto error_return;
elf_sym_hashes (abfd) = sym_hash;
dt_needed = false;
if (! dynamic)
{
/* If we are creating a shared library, create all the dynamic
@@ -1085,7 +1088,12 @@ elf_link_add_object_symbols (abfd, info)
{
name = elf_dt_name (abfd);
if (*name == '\0')
add_needed = false;
{
if (elf_dt_soname (abfd) != NULL)
dt_needed = true;
add_needed = false;
}
}
s = bfd_get_section_by_name (abfd, ".dynamic");
if (s != NULL)
@@ -1863,6 +1871,53 @@ elf_link_add_object_symbols (abfd, info)
(*bed->elf_backend_hide_symbol) (info, h);
break;
}
if (dt_needed && definition
&& (h->elf_link_hash_flags
& ELF_LINK_HASH_REF_REGULAR) != 0)
{
bfd_size_type oldsize;
bfd_size_type strindex;
/* The symbol from a DT_NEEDED object is referenced from
the regular object to create a dynamic executable. We
have to make sure there is a DT_NEEDED entry for it. */
dt_needed = false;
oldsize = _bfd_stringtab_size (elf_hash_table (info)->dynstr);
strindex = _bfd_stringtab_add (elf_hash_table (info)->dynstr,
elf_dt_soname (abfd),
true, false);
if (strindex == (bfd_size_type) -1)
goto error_return;
if (oldsize
== _bfd_stringtab_size (elf_hash_table (info)->dynstr))
{
asection *sdyn;
Elf_External_Dyn *dyncon, *dynconend;
sdyn = bfd_get_section_by_name (elf_hash_table (info)->dynobj,
".dynamic");
BFD_ASSERT (sdyn != NULL);
dyncon = (Elf_External_Dyn *) sdyn->contents;
dynconend = (Elf_External_Dyn *) (sdyn->contents +
sdyn->_raw_size);
for (; dyncon < dynconend; dyncon++)
{
Elf_Internal_Dyn dyn;
elf_swap_dyn_in (elf_hash_table (info)->dynobj,
dyncon, &dyn);
BFD_ASSERT (dyn.d_tag != DT_NEEDED ||
dyn.d_un.d_val != strindex);
}
}
if (! elf_add_dynamic_entry (info, DT_NEEDED, strindex))
goto error_return;
}
}
}