Can I link a.out .o with ELF?

H . J . Lu hjl@valinux.com
Mon Jun 5 07:46:00 GMT 2000


On Mon, Jun 05, 2000 at 11:30:08AM +1000, Alan Modra wrote:
> On Sun, 4 Jun 2000, H . J . Lu wrote:
> 
> > I believe I used to be able to link a .o file in a.out on an ELF
> > system. But now I got
> > 
> > # gcc -o aout x.o
> > collect2: ld terminated with signal 11 [Segmentation fault], core dumped
> 
> 

This patch seems to work for me. Any comments?

BTW, ld still got core dump when it tried to use a .o file in a.out
to created an ELF DSO, i.e.

# gcc -shared -o libaout.so aout.o

where aout.o is a non-PIC a.out .o file. I assume that is not supported
at all.

Thanks.


-- 
H.J. Lu (hjl@gnu.org)
---
2000-06-05  H.J. Lu  <hjl@gnu.org>

	* elflink.h (elf_fix_symbol_flags): Handle the ELF_LINK_NON_ELF
	bit set on the indirect symbol.
	(elf_link_output_extsym): Don't output the indirect symbol even
	if the ELF_LINK_NON_ELF bit is set.

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 14:27:42
@@ -3287,6 +3287,36 @@ elf_fix_symbol_flags (h, eif)
      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)
+    {
+      const char *p;
+      char *def;
+      struct elf_link_hash_entry *d;
+
+      /* If this is a default version (the name contains @@),
+	 look up the symbol without the version. We have to set
+	 the ELF_LINK_NON_ELF bit on the default version if the
+	 indirect symbol has the bit set.  */
+
+      p = strchr (h->root.root.string, ELF_VER_CHR);
+      if (p != NULL && p[1] == ELF_VER_CHR)
+	{
+	  def = alloca (p - h->root.root.string + 1);
+	  memcpy (def, h->root.root.string, p - h->root.root.string);
+	  def[p - h->root.root.string] = '\0';
+
+	  d = elf_link_hash_lookup (elf_hash_table (eif->info), def,
+				    false, false, false);
+	} 
+      else
+	d = NULL;
+
+      if (d && (d->elf_link_hash_flags & ELF_LINK_NON_ELF) != 0
+	  && d->root.type == bfd_link_hash_indirect)
+	h->elf_link_hash_flags |= ELF_LINK_NON_ELF;
+    }
+
   if ((h->elf_link_hash_flags & ELF_LINK_NON_ELF) != 0)
     {
       if (h->root.type != bfd_link_hash_defined
@@ -5031,9 +5061,9 @@ elf_link_output_extsym (h, data)
          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;
+         the indirect symbol is non-ELF, we don't fall through and
+	 output it since it is handled in elf_fix_symbol_flags ().  */
+      return true;
 
       /* Fall through.  */
     case bfd_link_hash_warning:


More information about the Binutils mailing list