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

@ -1,3 +1,17 @@
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.
2000-07-19 H.J. Lu <hjl@gnu.org>
* elf.c (_bfd_elf_print_private_bfd_data): Handle DT_CONFIG,

View File

@ -627,6 +627,7 @@ extern boolean bfd_elf64_size_dynamic_sections
const char * const *, struct bfd_link_info *, struct sec **,
struct bfd_elf_version_tree *));
extern void bfd_elf_set_dt_needed_name PARAMS ((bfd *, const char *));
extern void bfd_elf_set_dt_needed_soname PARAMS ((bfd *, const char *));
extern const char *bfd_elf_get_dt_soname PARAMS ((bfd *));
/* Return an upper bound on the number of bytes required to store a

View File

@ -627,6 +627,7 @@ extern boolean bfd_elf64_size_dynamic_sections
const char * const *, struct bfd_link_info *, struct sec **,
struct bfd_elf_version_tree *));
extern void bfd_elf_set_dt_needed_name PARAMS ((bfd *, const char *));
extern void bfd_elf_set_dt_needed_soname PARAMS ((bfd *, const char *));
extern const char *bfd_elf_get_dt_soname PARAMS ((bfd *));
/* Return an upper bound on the number of bytes required to store a

View File

@ -838,6 +838,14 @@ struct elf_obj_tdata
one. */
const char *dt_name;
/* When a reference in a regular object is resolved by a shared
object is loaded into via the DT_NEEDED entries by the linker
ELF emulation code, we need to add the shared object to the
DT_NEEDED list of the resulting binary to indicate the dependency
as if the -l option is passed to the linker. This field holds the
name of the loaded shared object. */
const char *dt_soname;
/* Irix 5 often screws up the symbol table, sorting local symbols
after global symbols. This flag is set if the symbol table in
this BFD appears to be screwed up. If it is, we ignore the
@ -915,6 +923,7 @@ struct elf_obj_tdata
#define elf_local_got_offsets(bfd) (elf_tdata(bfd) -> local_got.offsets)
#define elf_local_ptr_offsets(bfd) (elf_tdata(bfd) -> linker_section_pointers)
#define elf_dt_name(bfd) (elf_tdata(bfd) -> dt_name)
#define elf_dt_soname(bfd) (elf_tdata(bfd) -> dt_soname)
#define elf_bad_symtab(bfd) (elf_tdata(bfd) -> bad_symtab)
#define elf_flags_init(bfd) (elf_tdata(bfd) -> flags_init)
#define elf_linker_section(bfd,n) (elf_tdata(bfd) -> linker_section[(int)n])

View File

@ -1050,6 +1050,16 @@ bfd_elf_set_dt_needed_name (abfd, name)
elf_dt_name (abfd) = name;
}
void
bfd_elf_set_dt_needed_soname (abfd, name)
bfd *abfd;
const char *name;
{
if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
&& bfd_get_format (abfd) == bfd_object)
elf_dt_soname (abfd) = name;
}
/* Get the list of DT_NEEDED entries for a link. This is a hook for
the linker ELF emulation code. */

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