This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Bug report: objc classes linked in wrong order


On Tue, May 09, 2000 at 12:05:15PM -0700, H . J . Lu wrote:
> On Mon, May 08, 2000 at 05:01:06PM +0100, nicola@brainstorm.co.uk wrote:
> > Hi - I have a bug report.
> > 
> > The problem description is as follows:
> > 
> > (*)  [standard behaviour] if I have two libraries implementing the same
> > function, say
> > 
> > void hello (void);
> > 
> > and I link an executable with the two libraries, the `hello` from the
> > first library given on the command line gets used.  This happens with both
> > static and shared library.
> > 
> > (*) if I do the same with an Objective-C class, i.e. I have two libraries
> > implementing the same method of the same class, what happens is:
> > 
> > [standard behaviour] if I link an executable with the two libraries, the
> > method of the class from the first library on the command line gets used
> > when the two libraries are static.
> > 
> > [the problem] The weird thing is when I link dynamically the two libraries
> > in:  then - consistently - the class from the second library on the
> > command line gets used instead of the first as it should have.
> > 
> > I was able to isolate the problem and to create a complete test showing
> > the problem, which I enclose in attach.
> > 
> > Please notice that I am willing to actively help to fix the bug - only I
> > am not a linker/compiler expert, so I'm pretty stuck and don't know what
> > to look at.  But it is quite important to me that the bug gets fixed.
> > 
> > --
> > 
> > I am using binutils-2.9.1.0.23 and almost everything which comes with
> > RedHat 6.1.  I have the bug with both the old and the latest CVS egcs
> > compiler.
> > 
> > Thank you for any help.
> 
> It is a very interesting problem. I know very little about Objective-C.
> From the asm output, I have an impression that the Objective-C class
> implemenation is registered via the .ctors section. When you link with
> 
> # cc -I./ -L/user/hjl/bugs/objc/shared/bug.report/install -o test-shared test.o -ltest1 -ltest2 -lobjc -lpthread
> 
> "-ltest1 -ltest2 -lobjc -lpthread -lgcc -lc -lgcc" is passed to the
> linker. The dynamic linker in glibc 2.1 will process the .ctors section
> in the reverse order. That is
> 
> 11951:  calling init: /lib/libc.so.6
> 11951:  calling init: /lib/libpthread.so.0
> 11951:  calling init: ./install/libtest2.so.0
> 11951:  calling init: ./install/libtest1.so.0
> 
> As the result, the implemenation in libtest2 gets register first. For
> the static link, libtest2.a is not even used at all. I don't know for
> sure what the right answer for it is.
> 

This patch seems to work for me. But I know nothing about Objective-C.
It may be the wrong thing to do.


H.J.
----
2000-05-09  H.J. Lu  (hjl@gnu.org)

	* libobjc/class.c (__objc_add_class_to_hash): Override the
	previous implementation.
	* libobjc/init.c (__objc_tree_insert_class): Likewise.

diff -upr -x CVS ../../../import/gcc-2.95.x/egcs/libobjc/class.c libobjc/class.c
--- ../../../import/gcc-2.95.x/egcs/libobjc/class.c	Sun Sep 20 18:22:06 1998
+++ libobjc/class.c	Tue May  9 14:56:09 2000
@@ -88,6 +88,14 @@ __objc_add_class_to_hash(Class class)
       ++class_number;
       hash_add (&__objc_class_hash, class->name, class);
     }
+  else if (h_class != class)
+    {
+      /* Override the previouse implementation. */
+      CLS_SETNUMBER(class, CLS_GETNUMBER (h_class));
+      CLS_SETNUMBER(class->class_pointer, CLS_GETNUMBER (h_class));
+      hash_remove (__objc_class_hash, class->name);
+      hash_add (&__objc_class_hash, class->name, class);
+    }
 
   objc_mutex_unlock(__objc_runtime_mutex);
 }
diff -upr -x CVS ../../../import/gcc-2.95.x/egcs/libobjc/init.c libobjc/init.c
--- ../../../import/gcc-2.95.x/egcs/libobjc/init.c	Mon Jun 21 07:30:46 1999
+++ libobjc/init.c	Tue May  9 14:54:52 2000
@@ -174,6 +174,16 @@ __objc_tree_insert_class (objc_class_tre
 			    class->name);
 	      return tree;
 	    }
+	  else if (strcmp (((objc_class_tree*)list->head)->class->name,
+			   class->name) == 0)
+	    {
+	      DEBUG_PRINTF ("1. a different implementation of class %s was previously inserted\n",
+			    class->name);
+
+	      /* Override the previouse implementation. */
+	      ((objc_class_tree*)list->head)->class = class;
+	      return tree;
+	    }
 	  list = list->tail;
 	}
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]