aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2005-01-25 01:40:04 +0000
committerAlan Modra <amodra@gmail.com>2005-01-25 01:40:04 +0000
commit7e9f086769d3ad7ed3ee0562888fbb72747a02b1 (patch)
tree950000f8f077c7092c4ef3c2329f2a5f3591df9d /bfd
parent80524dabacf47f34dd5a6e6c5f4efe88c8c04614 (diff)
downloadgdb-7e9f086769d3ad7ed3ee0562888fbb72747a02b1.zip
gdb-7e9f086769d3ad7ed3ee0562888fbb72747a02b1.tar.gz
gdb-7e9f086769d3ad7ed3ee0562888fbb72747a02b1.tar.bz2
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.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog13
-rw-r--r--bfd/elflink.c85
2 files changed, 61 insertions, 37 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index a73c5c6..7a83525 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 7a02d34..328e780 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -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);
-
- for (extdyn = sdyn->contents;
- extdyn < sdyn->contents + sdyn->size;
- extdyn += bed->s->sizeof_dyn)
- {
- Elf_Internal_Dyn dyn;
+ if (sdyn != NULL)
+ 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)
{