This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
Re: Can I link a.out .o with ELF?
On Mon, Jun 05, 2000 at 08:39:06AM -0700, Ian Lance Taylor wrote:
> Date: Tue, 6 Jun 2000 00:28:01 +1000 (EST)
> From: Alan Modra <alan@linuxcare.com.au>
>
> Index: elflink.h
> ===================================================================
> RCS file: /cvs/src/src/bfd/elflink.h,v
> retrieving revision 1.58
> diff -u -p -r1.58 elflink.h
> --- elflink.h 2000/05/30 20:51:36 1.58
> +++ elflink.h 2000/06/05 14:23:33
> @@ -1741,6 +1741,20 @@ elf_link_add_object_symbols (abfd, info)
> ht = (struct elf_link_hash_entry *) hi->root.u.i.link;
> (*bed->elf_backend_copy_indirect_symbol) (ht, hi);
>
> + if ((hi->elf_link_hash_flags & ELF_LINK_NON_ELF) != 0)
> + {
> + if (dynamic)
> + hi->elf_link_hash_flags |=
> + ELF_LINK_HASH_DEF_DYNAMIC;
> + else
> + hi->elf_link_hash_flags |=
> + ELF_LINK_HASH_DEF_REGULAR;
> +
> + ht->elf_link_hash_flags |=
> + (ELF_LINK_HASH_REF_REGULAR
> + | ELF_LINK_HASH_REF_REGULAR_NONWEAK);
> + }
> +
> /* See if the new flags lead us to realize that
> the symbol must be dynamic. */
> if (! dynsym)
>
> I don't understand why you would ever want to set DEF_DYNAMIC here.
> You should only get ELF_LINK_NON_ELF when the symbol appears in a
> non-ELF file. The ELF linker does not support linking against a
> non-ELF dynamic library.
>
> It should only be necessary to set DEF_REGULAR if the symbol is in
> fact defined in a non-ELF file. Similarly, it should only be
> necessary to set REF_REGULAR and REF_REGULAR_NONWEAK if the symbol is
> referenced in a non-ELF file. The code above may well be correct on
> this, although I don't really understand why we need to set them here
> as opposed to various other places.
It is not needed.
>
> @@ -3283,11 +3297,15 @@ elf_fix_symbol_flags (h, eif)
> struct elf_link_hash_entry *h;
> struct elf_info_failed *eif;
> {
> + struct elf_link_hash_entry *ho = h;
> + while (h->root.type == bfd_link_hash_indirect)
> + h = (struct elf_link_hash_entry *) h->root.u.i.link;
> +
> /* If this symbol was mentioned in a non-ELF file, try to set
> DEF_REGULAR and REF_REGULAR correctly. This is the only way to
> permit a non-ELF file to correctly refer to a symbol defined in
> an ELF dynamic object. */
> - if ((h->elf_link_hash_flags & ELF_LINK_NON_ELF) != 0)
> + if ((ho->elf_link_hash_flags & ELF_LINK_NON_ELF) != 0)
> {
> if (h->root.type != bfd_link_hash_defined
> && h->root.type != bfd_link_hash_defweak)
>
> I don't think it is right to change h here. elf_fix_symbol_flags
> should get called for every h.
>
How about the patch enclosed here? It will only follow the indirect
symbol with the ELF_LINK_NON_ELF bit set.
>
> What happens if you just patch elf_link_assign_sym_version to work on
> NON_ELF symbols as well as DEF_REGULAR symbols?
>
The problem is we have to call _bfd_elf_link_record_dynamic_symbol on
the default symbol. Follow the indirect symbol will do it.
H.J.
----
Index: elflink.h
===================================================================
RCS file: /work/cvs/gnu/binutils/bfd/elflink.h,v
retrieving revision 1.30
diff -u -p -r1.30 elflink.h
--- elflink.h 2000/05/30 21:05:11 1.30
+++ elflink.h 2000/06/05 17:05:07
@@ -3289,6 +3289,9 @@ elf_fix_symbol_flags (h, eif)
an ELF dynamic object. */
if ((h->elf_link_hash_flags & ELF_LINK_NON_ELF) != 0)
{
+ while (h->root.type == bfd_link_hash_indirect)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
if (h->root.type != bfd_link_hash_defined
&& h->root.type != bfd_link_hash_defweak)
h->elf_link_hash_flags |= (ELF_LINK_HASH_REF_REGULAR
@@ -5030,10 +5033,8 @@ elf_link_output_extsym (h, data)
symbol foo@@GNU_1.2 is the default, which should be used when
foo is used with no version, then we add an indirect symbol
foo which points to foo@@GNU_1.2. We ignore these symbols,
- since the indirected symbol is already in the hash table. If
- the indirect symbol is non-ELF, fall through and output it. */
- if ((h->elf_link_hash_flags & ELF_LINK_NON_ELF) == 0)
- return true;
+ since the indirected symbol is already in the hash table. */
+ return true;
/* Fall through. */
case bfd_link_hash_warning: