From 59474174039062373caaee75dbcce0e6a5760968 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 6 Feb 1995 23:23:37 +0000 Subject: [PATCH] * libelf.h (struct elf_link_hash_table): Add saw_needed field. * elfcode.h (elf_link_add_object_symbols): Set saw_needed if DT_NEEDED seen in .dynamic section. (elf_link_output_extsym): Warn if an undefined symbol is only referenced from a dynamic object, and not making a shared object, and saw_needed is false. * elf.c (_bfd_elf_link_hash_table_init): Initialize saw_needed. --- bfd/ChangeLog | 8 ++++++++ bfd/elfcode.h | 35 +++++++++++++++++++++++++++++++++-- bfd/libelf.h | 4 ++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 717d6c9fba..be78ac049c 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,13 @@ Mon Feb 6 14:25:24 1995 Ian Lance Taylor + * libelf.h (struct elf_link_hash_table): Add saw_needed field. + * elfcode.h (elf_link_add_object_symbols): Set saw_needed if + DT_NEEDED seen in .dynamic section. + (elf_link_output_extsym): Warn if an undefined symbol is + only referenced from a dynamic object, and not making a shared + object, and saw_needed is false. + * elf.c (_bfd_elf_link_hash_table_init): Initialize saw_needed. + * libelf.h (ELF_LINK_HASH_DEFINED_WEAK): Don't define. * elfcode.h (elf_link_add_object_symbols): Don't clear or set ELF_LINK_HASH_DEFINED_WEAK. diff --git a/bfd/elfcode.h b/bfd/elfcode.h index a99b1d9d7f..a5f0ffda0b 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -4249,9 +4249,9 @@ elf_link_add_object_symbols (abfd, info) dyn.d_un.d_val); if (name == NULL) goto error_return; - - break; } + if (dyn.d_tag == DT_NEEDED) + elf_hash_table (info)->saw_needed = true; } free (dynbuf); @@ -6059,6 +6059,37 @@ elf_link_output_extsym (h, data) Elf_Internal_Sym sym; asection *input_sec; + /* If we are not creating a shared library, and this symbol is + referenced by a shared library but is not defined anywhere, then + warn that it is undefined. If we do not do this, the runtime + linker will complain that the symbol is undefined when the + program is run. We don't have to worry about symbols that are + referenced by regular files, because we will already have issued + warnings for them. + + FIXME: If we are linking against an object which uses DT_NEEDED, + we don't give this warning, because it might be the case that the + needed dynamic object will define the symbols. Unfortunately, + this makes this type of check much less useful, but the only way + to fix it would be to locate the needed object and read its + symbol table. That seems like a real waste of time just to give + better error messages. */ + if (! finfo->info->relocateable + && ! finfo->info->shared + && ! elf_hash_table (finfo->info)->saw_needed + && h->root.type == bfd_link_hash_undefined + && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0 + && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0) + { + if (! ((*finfo->info->callbacks->undefined_symbol) + (finfo->info, h->root.root.string, h->root.u.undef.abfd, + (asection *) NULL, 0))) + { + /* FIXME: No way to return error. */ + abort (); + } + } + /* We don't want to output symbols that have never been mentioned by a regular file, or that we have been told to strip. However, if h->indx is set to -2, the symbol is used by a reloc and we must diff --git a/bfd/libelf.h b/bfd/libelf.h index 349f9fa68b..5fb58c0c2f 100644 --- a/bfd/libelf.h +++ b/bfd/libelf.h @@ -144,6 +144,10 @@ struct elf_link_hash_table /* The number of buckets in the hash table in the .hash section. This is based on the number of dynamic symbols. */ size_t bucketcount; + /* Whether we are linking against a dynamic object which has a + DT_NEEDED entry in the .dynamic section. This may need to become + a list of DT_NEEDED entries. */ + boolean saw_needed; }; /* Look up an entry in an ELF linker hash table. */