bfd/
* elflink.c (elf_link_add_object_symbols): Don't create link dynamic sections immediately when linking shared libs. Instead, wait until we know a lib is needed. (_bfd_elf_link_create_dynstrtab): Extract from.. (_bfd_elf_link_create_dynamic_sections_): ..here. (elf_add_dt_needed_tag): Call _bfd_elf_link_create_dynstrtab and _bfd_elf_link_create_dynamic_sections. Add abfd param. Allow for non-existent .dynamic. (elf_link_output_extsym): Don't complain about undefined symbols in as-needed dynamic libs that aren't actually linked. ld/ * emultempl/elf32.em (gld${EMULATION_NAME}_try_needed): Formatting. (gld${EMULATION_NAME}_after_open): Ignore needed libs if they were only needed by an as-needed lib that didn't get linked.
This commit is contained in:
parent
80524dabac
commit
7e9f086769
4 changed files with 79 additions and 42 deletions
|
@ -1,3 +1,16 @@
|
|||
2005-01-25 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elflink.c (elf_link_add_object_symbols): Don't create link dynamic
|
||||
sections immediately when linking shared libs. Instead, wait until
|
||||
we know a lib is needed.
|
||||
(_bfd_elf_link_create_dynstrtab): Extract from..
|
||||
(_bfd_elf_link_create_dynamic_sections_): ..here.
|
||||
(elf_add_dt_needed_tag): Call _bfd_elf_link_create_dynstrtab and
|
||||
_bfd_elf_link_create_dynamic_sections. Add abfd param. Allow
|
||||
for non-existent .dynamic.
|
||||
(elf_link_output_extsym): Don't complain about undefined symbols
|
||||
in as-needed dynamic libs that aren't actually linked.
|
||||
|
||||
2005-01-24 Andrew Cagney <cagney@gnu.org>
|
||||
|
||||
* configure: Regenerate, ../gettext.m4 was updated.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* ELF linking support for BFD.
|
||||
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
|
||||
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
@ -103,6 +103,25 @@ _bfd_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* Create a strtab to hold the dynamic symbol names. */
|
||||
static bfd_boolean
|
||||
_bfd_elf_link_create_dynstrtab (bfd *abfd, struct bfd_link_info *info)
|
||||
{
|
||||
struct elf_link_hash_table *hash_table;
|
||||
|
||||
hash_table = elf_hash_table (info);
|
||||
if (hash_table->dynobj == NULL)
|
||||
hash_table->dynobj = abfd;
|
||||
|
||||
if (hash_table->dynstr == NULL)
|
||||
{
|
||||
hash_table->dynstr = _bfd_elf_strtab_init ();
|
||||
if (hash_table->dynstr == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Create some sections which will be filled in with dynamic linking
|
||||
information. ABFD is an input file which requires dynamic sections
|
||||
to be created. The dynamic sections take up virtual memory space
|
||||
|
@ -125,12 +144,10 @@ _bfd_elf_link_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
|
|||
if (elf_hash_table (info)->dynamic_sections_created)
|
||||
return TRUE;
|
||||
|
||||
/* Make sure that all dynamic sections use the same input BFD. */
|
||||
if (elf_hash_table (info)->dynobj == NULL)
|
||||
elf_hash_table (info)->dynobj = abfd;
|
||||
else
|
||||
abfd = elf_hash_table (info)->dynobj;
|
||||
if (!_bfd_elf_link_create_dynstrtab (abfd, info))
|
||||
return FALSE;
|
||||
|
||||
abfd = elf_hash_table (info)->dynobj;
|
||||
bed = get_elf_backend_data (abfd);
|
||||
|
||||
flags = bed->dynamic_sec_flags;
|
||||
|
@ -186,14 +203,6 @@ _bfd_elf_link_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
|
|||
|| ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY))
|
||||
return FALSE;
|
||||
|
||||
/* Create a strtab to hold the dynamic symbol names. */
|
||||
if (elf_hash_table (info)->dynstr == NULL)
|
||||
{
|
||||
elf_hash_table (info)->dynstr = _bfd_elf_strtab_init ();
|
||||
if (elf_hash_table (info)->dynstr == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
s = bfd_make_section (abfd, ".dynamic");
|
||||
if (s == NULL
|
||||
|| ! bfd_set_section_flags (abfd, s, flags)
|
||||
|
@ -2746,7 +2755,8 @@ _bfd_elf_add_dynamic_entry (struct bfd_link_info *info,
|
|||
1 if a DT_NEEDED tag already exists, and 0 on success. */
|
||||
|
||||
static int
|
||||
elf_add_dt_needed_tag (struct bfd_link_info *info,
|
||||
elf_add_dt_needed_tag (bfd *abfd,
|
||||
struct bfd_link_info *info,
|
||||
const char *soname,
|
||||
bfd_boolean do_it)
|
||||
{
|
||||
|
@ -2754,6 +2764,9 @@ elf_add_dt_needed_tag (struct bfd_link_info *info,
|
|||
bfd_size_type oldsize;
|
||||
bfd_size_type strindex;
|
||||
|
||||
if (!_bfd_elf_link_create_dynstrtab (abfd, info))
|
||||
return -1;
|
||||
|
||||
hash_table = elf_hash_table (info);
|
||||
oldsize = _bfd_elf_strtab_size (hash_table->dynstr);
|
||||
strindex = _bfd_elf_strtab_add (hash_table->dynstr, soname, FALSE);
|
||||
|
@ -2768,26 +2781,28 @@ elf_add_dt_needed_tag (struct bfd_link_info *info,
|
|||
|
||||
bed = get_elf_backend_data (hash_table->dynobj);
|
||||
sdyn = bfd_get_section_by_name (hash_table->dynobj, ".dynamic");
|
||||
BFD_ASSERT (sdyn != NULL);
|
||||
if (sdyn != NULL)
|
||||
for (extdyn = sdyn->contents;
|
||||
extdyn < sdyn->contents + sdyn->size;
|
||||
extdyn += bed->s->sizeof_dyn)
|
||||
{
|
||||
Elf_Internal_Dyn dyn;
|
||||
|
||||
for (extdyn = sdyn->contents;
|
||||
extdyn < sdyn->contents + sdyn->size;
|
||||
extdyn += bed->s->sizeof_dyn)
|
||||
{
|
||||
Elf_Internal_Dyn dyn;
|
||||
|
||||
bed->s->swap_dyn_in (hash_table->dynobj, extdyn, &dyn);
|
||||
if (dyn.d_tag == DT_NEEDED
|
||||
&& dyn.d_un.d_val == strindex)
|
||||
{
|
||||
_bfd_elf_strtab_delref (hash_table->dynstr, strindex);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
bed->s->swap_dyn_in (hash_table->dynobj, extdyn, &dyn);
|
||||
if (dyn.d_tag == DT_NEEDED
|
||||
&& dyn.d_un.d_val == strindex)
|
||||
{
|
||||
_bfd_elf_strtab_delref (hash_table->dynstr, strindex);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (do_it)
|
||||
{
|
||||
if (!_bfd_elf_link_create_dynamic_sections (hash_table->dynobj, info))
|
||||
return -1;
|
||||
|
||||
if (!_bfd_elf_add_dynamic_entry (info, DT_NEEDED, strindex))
|
||||
return -1;
|
||||
}
|
||||
|
@ -3282,11 +3297,6 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
|
|||
file. */
|
||||
bfd_section_list_clear (abfd);
|
||||
|
||||
/* If this is the first dynamic object found in the link, create
|
||||
the special sections required for dynamic linking. */
|
||||
if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
|
||||
goto error_return;
|
||||
|
||||
/* Find the name to use in a DT_NEEDED entry that refers to this
|
||||
object. If the object has a DT_SONAME entry, we use it.
|
||||
Otherwise, if the generic linker stuck something in
|
||||
|
@ -3303,7 +3313,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
|
|||
will need to know it. */
|
||||
elf_dt_name (abfd) = soname;
|
||||
|
||||
ret = elf_add_dt_needed_tag (info, soname, add_needed);
|
||||
ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed);
|
||||
if (ret < 0)
|
||||
goto error_return;
|
||||
|
||||
|
@ -3953,7 +3963,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
|
|||
elf_dyn_lib_class (abfd) &= ~DYN_AS_NEEDED;
|
||||
|
||||
add_needed = TRUE;
|
||||
ret = elf_add_dt_needed_tag (info, soname, add_needed);
|
||||
ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed);
|
||||
if (ret < 0)
|
||||
goto error_free_vers;
|
||||
|
||||
|
@ -6160,6 +6170,7 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
|
|||
if (h->root.type == bfd_link_hash_undefined
|
||||
&& h->ref_dynamic
|
||||
&& !h->ref_regular
|
||||
&& (elf_dyn_lib_class (h->root.u.undef.abfd) & DYN_AS_NEEDED) == 0
|
||||
&& ! elf_link_check_versioned_symbol (finfo->info, bed, h)
|
||||
&& finfo->info->unresolved_syms_in_shared_libs != RM_IGNORE)
|
||||
{
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2005-01-25 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* emultempl/elf32.em (gld${EMULATION_NAME}_try_needed): Formatting.
|
||||
(gld${EMULATION_NAME}_after_open): Ignore needed libs if they were
|
||||
only needed by an as-needed lib that didn't get linked.
|
||||
|
||||
2005-01-23 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* ld.texinfo (Output Section Keywords <CONSTRUCTORS>): Correct
|
||||
|
|
|
@ -13,7 +13,7 @@ cat >e${EMULATION_NAME}.c <<EOF
|
|||
|
||||
/* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME}
|
||||
Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||
2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
Written by Steve Chamberlain <sac@cygnus.com>
|
||||
ELF support by Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
|
@ -398,9 +398,8 @@ cat >>e${EMULATION_NAME}.c <<EOF
|
|||
/* Tell the ELF linker that we don't want the output file to have a
|
||||
DT_NEEDED entry for this file at all if the entry is from a file
|
||||
with DYN_NO_ADD_NEEDED. */
|
||||
if (needed->by
|
||||
&& (bfd_elf_get_dyn_lib_class (needed->by)
|
||||
& DYN_NO_ADD_NEEDED) != 0)
|
||||
if (needed->by != NULL
|
||||
&& (bfd_elf_get_dyn_lib_class (needed->by) & DYN_NO_ADD_NEEDED) != 0)
|
||||
class |= DYN_NO_NEEDED | DYN_NO_ADD_NEEDED;
|
||||
|
||||
bfd_elf_set_dyn_lib_class (abfd, class);
|
||||
|
@ -785,9 +784,17 @@ gld${EMULATION_NAME}_after_open (void)
|
|||
struct dt_needed n, nn;
|
||||
int force;
|
||||
|
||||
/* If the lib that needs this one was --as-needed and wasn't
|
||||
found to be needed, then this lib isn't needed either. */
|
||||
if (l->by != NULL
|
||||
&& (bfd_elf_get_dyn_lib_class (l->by) & DYN_AS_NEEDED) != 0)
|
||||
continue;
|
||||
|
||||
/* If we've already seen this file, skip it. */
|
||||
for (ll = needed; ll != l; ll = ll->next)
|
||||
if (strcmp (ll->name, l->name) == 0)
|
||||
if ((ll->by == NULL
|
||||
|| (bfd_elf_get_dyn_lib_class (ll->by) & DYN_AS_NEEDED) == 0)
|
||||
&& strcmp (ll->name, l->name) == 0)
|
||||
break;
|
||||
if (ll != l)
|
||||
continue;
|
||||
|
|
Loading…
Reference in a new issue