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:
parent
019148e439
commit
7481689898
6 changed files with 91 additions and 1 deletions
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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])
|
||||
|
|
10
bfd/elf.c
10
bfd/elf.c
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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,8 +1088,13 @@ elf_link_add_object_symbols (abfd, info)
|
|||
{
|
||||
name = elf_dt_name (abfd);
|
||||
if (*name == '\0')
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue