public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: Bug report: objc classes linked in wrong order
@ 2000-05-24  7:07 nicola
  0 siblings, 0 replies; 16+ messages in thread
From: nicola @ 2000-05-24  7:07 UTC (permalink / raw)
  To: gcc

[Forgot to post to this list.]

> > I did not even know that 'constructor priorities' exist - I think this
> > would certainly be the best solution.
>
> They're not applicable across different shared libraries.

I don't know much about the subject, but by looking at the code and info I
had been pointed to (thanks nickc) I have the impression you are right,
constructor priorities don't seem to be useful in this context.

Anybody has any other idea about of how to have the NXConstantString class
from a shared library to be linked instead of the NXConstantString from a
shared libobjc when linking both libraries ?

Otherwise, we could use the trick I am using on my system, with the
function etc (see previous post) - it works quite happily.

If anybody can suggest a better alternative strategy, I am willing to
implement it (try implementing it) myself - otherwise please consider
using the trick - it's not so dirty after all.

The only other solution I can think of is simply not to compile in
NXConstantString neither in the static nor in the shared objective-C
runtime library.  This would be clean, but would also mean that objc
programs not linked with a library providing an implementation of
NXConstantString would not run at all.

-

I have been notified by the FSF that my copyright assignment for GCC has
been registered, so when gcc experienced people find some time to have a
look at the patches to build a shared libobjc (the preliminary to all this
discussion), that would be nice.

Thanks to anyone for help and suggestions, really helpful.


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Bug report: objc classes linked in wrong order
  2000-05-30 10:45         ` nicola
  2000-05-30 11:11           ` Helge Hess
@ 2000-05-30 14:43           ` Richard Henderson
  1 sibling, 0 replies; 16+ messages in thread
From: Richard Henderson @ 2000-05-30 14:43 UTC (permalink / raw)
  To: nicola; +Cc: law, egcs, ovidiu, gcc

On Tue, May 30, 2000 at 07:47:02PM +0100, nicola@brainstorm.co.uk wrote:
> I could try making weak the module constructor
> 
>   _GLOBAL_.I..._.._.._egcs_20000501_libobjc_NXConstStr.mV7ccEc
> 
> in some way (is that what you are suggesting ?).

No.  In fact, that function should not even be public (normally),
since it is called from .ctors.

What should be public and weak is _OBJC_CLASS_NXConstantString.
That's the piece of data that (apparently) contains all of the
data relevant to the class.  If you make that weak, then the
reference to it from _OBJC_SYMBOLS will point to the strong version.

As long as __objc_exec_class is smart enough to recognize when
one class is being registered twice, and do nothing, you should
be fine.


r~

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Bug report: objc classes linked in wrong order
  2000-05-30 10:45         ` nicola
@ 2000-05-30 11:11           ` Helge Hess
  2000-05-30 14:43           ` Richard Henderson
  1 sibling, 0 replies; 16+ messages in thread
From: Helge Hess @ 2000-05-30 11:11 UTC (permalink / raw)
  To: nicola; +Cc: law, egcs, ovidiu, gcc

Hi,

if I got this discussion right the whole point is to replace
NXConstantString with NSConstantString ?

What is wrong with patching NXConstantString at runtime (rebasing it's
superclass to NSString and adding NSString functionality using
categories) ?
All that linking stuff looks far to complicated to me and probably isn't
really worth the effort.

I also do prefer having a separate libobjc for GNUstep environments
anyway (for various reasons). What's missing here is a reliable way to
get compiler-specific information (basically the config.h for libobjc).

Helge

nicola@brainstorm.co.uk wrote:
> On Tue, 30 May 2000 law@cygnus.com wrote:
> >   > I can't see any function or symbol we could make weak.
> >   > Making __objc_exec_class weak is not what we want - that function is
> >   > global.  The classes to load are got accessing directly the pointer passed
> >   > as argument of __objc_exec_class - don't see what we can make weak here.
> 
> > Start by ignoring all the Objective-C stuff.  Ultimately you have a hunk of
> > code.  That code is contained within a function, which in turn is contained
> > within a .o file, which is contained within a .a file.
> 
> Uhm.
> 
> Let's see if I can get it then.
> 
> In gcc/objc/objc-act.c I have:
> 
> static const char *
> build_module_descriptor ()
> {
>  // ...
> 
>  /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
> 
>  // ...
> }
> 
> [It outputs the code inside comment]
> 
> I could try making weak the module constructor
> 
>   _GLOBAL_.I..._.._.._egcs_20000501_libobjc_NXConstStr.mV7ccEc
> 
> in some way (is that what you are suggesting ?).  Don't know how useful
> could that be, since I need to override it in the GNUstep library (or in
> any other lib defining its own version of NXConstantString) with a
> constructor with exactly the same name - am I correct ?
> If that can be reasonably done, then I think it could be a nice solution.
> 
> Otherwise, the module constructor basically contains a call to the
> function objc_execClass, passing a fixed pointer, which then reads in what
> the pointer points to, information on selectors and classes to load, and
> loads them.  I don't think we can do anything here, because GNUstep needs
> to have NXConstantString in a different place in the class inheritance
> tree, so as soon as the class is put by the run-time in the class
> inheritance tree, that's the end of it.

-- 
SKYRIX-OS  Web Operating System       - http://www.skyrix.com
SKYRIX-IAS IntraNet Application Suite - http://www.skyrix.com

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Bug report: objc classes linked in wrong order
  2000-05-30  7:50       ` Jeffrey A Law
@ 2000-05-30 10:45         ` nicola
  2000-05-30 11:11           ` Helge Hess
  2000-05-30 14:43           ` Richard Henderson
  0 siblings, 2 replies; 16+ messages in thread
From: nicola @ 2000-05-30 10:45 UTC (permalink / raw)
  To: law; +Cc: egcs, ovidiu, gcc

On Tue, 30 May 2000 law@cygnus.com wrote:

>
>   In message < Pine.LNX.4.10.10005301151001.2211-100000@lin9.brainstorm.co.uk >yo
> u write:
>   > I can't see any function or symbol we could make weak.
>   > Making __objc_exec_class weak is not what we want - that function is
>   > global.  The classes to load are got accessing directly the pointer passed
>   > as argument of __objc_exec_class - don't see what we can make weak here.

> Start by ignoring all the Objective-C stuff.  Ultimately you have a hunk of
> code.  That code is contained within a function, which in turn is contained
> within a .o file, which is contained within a .a file.

Uhm.

Let's see if I can get it then.

In gcc/objc/objc-act.c I have:

static const char *
build_module_descriptor ()
{
 // ...

 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */

 // ...
}

[It outputs the code inside comment]

I could try making weak the module constructor

  _GLOBAL_.I..._.._.._egcs_20000501_libobjc_NXConstStr.mV7ccEc

in some way (is that what you are suggesting ?).  Don't know how useful
could that be, since I need to override it in the GNUstep library (or in
any other lib defining its own version of NXConstantString) with a
constructor with exactly the same name - am I correct ?
If that can be reasonably done, then I think it could be a nice solution.

Otherwise, the module constructor basically contains a call to the
function objc_execClass, passing a fixed pointer, which then reads in what
the pointer points to, information on selectors and classes to load, and
loads them.  I don't think we can do anything here, because GNUstep needs
to have NXConstantString in a different place in the class inheritance
tree, so as soon as the class is put by the run-time in the class
inheritance tree, that's the end of it.


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Bug report: objc classes linked in wrong order
  2000-05-30  3:19     ` nicola
@ 2000-05-30  7:50       ` Jeffrey A Law
  2000-05-30 10:45         ` nicola
  0 siblings, 1 reply; 16+ messages in thread
From: Jeffrey A Law @ 2000-05-30  7:50 UTC (permalink / raw)
  To: nicola; +Cc: rth, hjl, egcs, ovidiu, gcc

  In message < Pine.LNX.4.10.10005301151001.2211-100000@lin9.brainstorm.co.uk >yo
u write:
  > I can't see any function or symbol we could make weak.
  > Making __objc_exec_class weak is not what we want - that function is
  > global.  The classes to load are got accessing directly the pointer passed
  > as argument of __objc_exec_class - don't see what we can make weak here.
Start by ignoring all the Objective-C stuff.  Ultimately you have a hunk of
code.  That code is contained within a function, which in turn is contained
within a .o file, which is contained within a .a file.

If so, then we can make the function weak.

We're talking about low level object file capabilities, not language
capabilities.


jeff

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Bug report: objc classes linked in wrong order
  2000-05-29 10:52   ` Jeffrey A Law
@ 2000-05-30  3:19     ` nicola
  2000-05-30  7:50       ` Jeffrey A Law
  0 siblings, 1 reply; 16+ messages in thread
From: nicola @ 2000-05-30  3:19 UTC (permalink / raw)
  To: law; +Cc: rth, hjl, egcs, ovidiu, gcc

>   > Can I make an objective-C class weak ?
> I can't think of a reason why that wouldn't work.


>   > I found no evidence of this - because each module has a list of classes to
>   > load, and loads them all - but I might be wrong - so please give me a hint
>   > if I actually can in some way make a class weak.


> But they are "loaded" by the linker by including them in the final
> executable, right?  If so, at the .s/.o level you make the appropriate
> function(s) weak, then you should be OK.

Uhm - hope you are right :-) - that would be nice if we could
have 'weak' classes.
To me it looks difficult because my understanding of it is as follows:

[from libobjc/init.c]

/* This function is called by constructor functions generated for each
   module compiled.  (_GLOBAL_$I$...) The purpose of this function is to
   gather the module pointers so that they may be processed by the
   initialization routines as soon as possible */

void
__objc_exec_class (Module_t module)

So, the constructor functions contain a call of this function for each
module that gets loaded (they indeed do).  The module is represented by a
structure, created at compile time [defined in libobjc/objc/objc-api.h].
A pointer to this structure is passed as argument to __objc_exec_class ().
__objc_exec_class () accesses the members of the module structure
getting the list of selectors and classes to register.
It accesses the list of classes as follows:

loop on i
{
  Class class = (Class) module->symtab->defs[i];
  ...
}

which returns a structure containing the information needed to register
the new class with the runtime.

I can't see any function or symbol we could make weak.
Making __objc_exec_class weak is not what we want - that function is
global.  The classes to load are got accessing directly the pointer passed
as argument of __objc_exec_class - don't see what we can make weak here.


Any idea ?

Thanks for discussing - that helps a lot - sorry if I miss some basic
point.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Bug report: objc classes linked in wrong order
  2000-05-26  8:38 ` nicola
  2000-05-27 15:07   ` Richard Henderson
@ 2000-05-29 10:52   ` Jeffrey A Law
  2000-05-30  3:19     ` nicola
  1 sibling, 1 reply; 16+ messages in thread
From: Jeffrey A Law @ 2000-05-29 10:52 UTC (permalink / raw)
  To: nicola; +Cc: rth, hjl, egcs, ovidiu, gcc

  In message < Pine.LNX.4.10.10005261722570.26308-100000@lin9.brainstorm.co.uk >y
ou write:
  > 
  > > > Anybody has any other idea about of how to have the NXConstantString cl
  > ass
  > > > from a shared library to be linked instead of the NXConstantString from
  >  a
  > > > shared libobjc when linking both libraries ?
  > >
  > > Make the non-preferred one weak.
  > 
  > Can I make an objective-C class weak ?
I can't think of a reason why that wouldn't work.

  > I found no evidence of this - because each module has a list of classes to
  > load, and loads them all - but I might be wrong - so please give me a hint
  > if I actually can in some way make a class weak.
But they are "loaded" by the linker by including them in the final
executable, right?  If so, at the .s/.o level you make the appropriate
function(s) weak, then you should be OK.

jeff
  > 
 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Bug report: objc classes linked in wrong order
  2000-05-26  8:38 ` nicola
@ 2000-05-27 15:07   ` Richard Henderson
  2000-05-29 10:52   ` Jeffrey A Law
  1 sibling, 0 replies; 16+ messages in thread
From: Richard Henderson @ 2000-05-27 15:07 UTC (permalink / raw)
  To: nicola; +Cc: law, hjl, egcs, ovidiu, gcc

On Fri, May 26, 2000 at 05:34:43PM +0100, nicola@brainstorm.co.uk wrote:
> Can I make an objective-C class weak ?

Perhaps with a change to the front end.  Certainly there's 
no reason why the front end shouldn't be able to mark all the
symbols for a particular class weak.


r~

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Bug report: objc classes linked in wrong order
       [not found] <20000524102254.A23847@cygnus.com>
@ 2000-05-26  8:38 ` nicola
  2000-05-27 15:07   ` Richard Henderson
  2000-05-29 10:52   ` Jeffrey A Law
  0 siblings, 2 replies; 16+ messages in thread
From: nicola @ 2000-05-26  8:38 UTC (permalink / raw)
  To: rth; +Cc: law, hjl, egcs, ovidiu, gcc

> > Anybody has any other idea about of how to have the NXConstantString class
> > from a shared library to be linked instead of the NXConstantString from a
> > shared libobjc when linking both libraries ?
>
> Make the non-preferred one weak.

Can I make an objective-C class weak ?

I found no evidence of this - because each module has a list of classes to
load, and loads them all - but I might be wrong - so please give me a hint
if I actually can in some way make a class weak.

But I liked your hint anyway, because using __attribute__((weak)) at least
can help to make the patch simpler.

--- ./init.c.orig	Mon May 15 10:34:03 2000
+++ init.c	Fri May 26 16:29:47 2000
@@ -26,6 +26,10 @@

 #include "runtime.h"

+/* Define this to 1 if you want to provide your own version of
+   NXConstantString in your library or user code */
+int __attribute__((weak)) _user_defined_NXConstantString = 0;
+
 /* The version number of this runtime.  This must match the number
    defined in gcc (objc-act.c) */
 #define OBJC_VERSION 8
@@ -469,7 +473,34 @@
   /* dummy counter */
   int i;

+  /* dummy pointer */
+  const char *p;
+
   DEBUG_PRINTF ("received module: %s\n", module->name);
+
+  if (_user_defined_NXConstantString == 1)
+    {
+      /* The user has overridden _user_defined_NXConstantString to
+	 tell us that he doesn't want us to load the library's
+	 NXConstantString implementation */
+      DEBUG_PRINTF ("Filtering out libobjc's NXConstantString at programmer's request:\n");
+
+      /* Search last occurrence of letter 'N' in the module name */
+      p = (char *)strrchr (module->name, 'N');
+      if (p)
+	{
+	  /* Found; compare string starting with this last 'N' to
+	     "NXConstStr.m" */
+	  if (strcmp (p, "NXConstStr.m") == 0)
+	    {
+	      /* it matches, so it is (should be) our NXConstantString
+                 module - don't load it */
+	      DEBUG_PRINTF ("Module not loaded\n");
+	      return;
+	    }
+	}
+      DEBUG_PRINTF ("Module loaded\n");
+    }

   /* check gcc version */
   init_check_module_version(module);


And then GNUstep can be patched as follows:

--- NSGCString.m	2000/03/17 13:13:07	1.77
+++ NSGCString.m	2000/05/26 15:26:11
@@ -23,6 +23,12 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
 */

+/*
+ * Tell libobjc not to include its own implementation of NXConstantString
+ */
+
+int _user_defined_NXConstantString = 1;
+
 #include <config.h>
 #include <base/preface.h>
 #include <Foundation/NSString.h>


Please notice that I already talked to the other GNUstep developers and we
agreed this solution could be acceptable.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Bug report: objc classes linked in wrong order
  2000-05-16  4:08         ` nicola
@ 2000-05-16 16:24           ` Richard Henderson
  0 siblings, 0 replies; 16+ messages in thread
From: Richard Henderson @ 2000-05-16 16:24 UTC (permalink / raw)
  To: nicola; +Cc: law, hjl, egcs, ovidiu

On Tue, May 16, 2000 at 01:05:57PM +0100, nicola@brainstorm.co.uk wrote:
> I did not even know that 'constructor priorities' exist - I think this
> would certainly be the best solution.

They're not applicable across different shared libraries.


r~

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Bug report: objc classes linked in wrong order
@ 2000-05-16 11:59 Nick Clifton
  0 siblings, 0 replies; 16+ messages in thread
From: Nick Clifton @ 2000-05-16 11:59 UTC (permalink / raw)
  To: nicola; +Cc: law, hjl, egcs, ovidiu

Hi Nicol

: > If so, it might be possible to use constructor priorities to
: > arrange for the libobjc version to have the lowest priority.  [ Maybe,
: > I'm not intimately familiar with the ctor/dtor priority code either.
: 
: I did not even know that 'constructor priorities' exist - I think this
: would certainly be the best solution.  If nobody else wants to look at it,
: could you give me a reference/hint about where to look for info about the
: constructor priorities (source code is ok, I just can't seem to find where
: is it) ?

Look at the following:

  gcc/invoke.texi  [search for init-priority]
  gcc/testsuite/g++.dg/special/*
  ld/ld.texinfo  [serach for 'priority']

Cheers
	Nick

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Bug report: objc classes linked in wrong order
  2000-05-15 13:00       ` Jeffrey A Law
@ 2000-05-16  4:08         ` nicola
  2000-05-16 16:24           ` Richard Henderson
  0 siblings, 1 reply; 16+ messages in thread
From: nicola @ 2000-05-16  4:08 UTC (permalink / raw)
  To: law; +Cc: hjl, egcs, ovidiu

> Is the root of the problem related to the order in which ctors are
> fired?

As far as I know, it should be.

> If so, it might be possible to use constructor priorities to
> arrange for the libobjc version to have the lowest priority.  [ Maybe,
> I'm not intimately familiar with the ctor/dtor priority code either.

I did not even know that 'constructor priorities' exist - I think this
would certainly be the best solution.  If nobody else wants to look at it,
could you give me a reference/hint about where to look for info about the
constructor priorities (source code is ok, I just can't seem to find where
is it) ?

Thank you very much for the hint - this looks like it would be a great way
of putting things in order.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Bug report: objc classes linked in wrong order
  2000-05-15  4:07     ` nicola
@ 2000-05-15 13:00       ` Jeffrey A Law
  2000-05-16  4:08         ` nicola
  0 siblings, 1 reply; 16+ messages in thread
From: Jeffrey A Law @ 2000-05-15 13:00 UTC (permalink / raw)
  To: nicola; +Cc: hjl, egcs, ovidiu

  In message < Pine.LNX.4.10.10005151138270.1862-100000@lin9.brainstorm.co.uk >yo
u write:
  > A good idea would simply be not to link in the NXConstantString
  > implementation in the shared libobjc.  I know people who like this idea a
  > lot.  My opinion is that this would not allow people to run objective-C
  > code without linking to GNUstep or another library providing an
  > implementation of NXConstantString - and we don't want to scare newcomers,
I think this would be a major mistake.

Having worked with shared libraries under Unix for about 10 years now
across a variety of platforms I've learned that providing different
routines in the shared vs archive libraries is one of the biggest 
mistakes you can make.  It leads to nothing but problems for developers
and users.  It's simply a losing proposition.

  > so my proposal is to use the following patch to libobjc/init.c:
Is the root of the problem related to the order in which ctors are
fired?  If so, it might be possible to use constructor priorities to
arrange for the libobjc version to have the lowest priority.  [ Maybe,
I'm not intimately familiar with the ctor/dtor priority code either.

From a design standpoint I'd prefer to avoid the kind of interface you
have proposed, it just seems like a bad design to have to expose that
kind of internal detail about the library's implementation to another
library.

jeff


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Bug report: objc classes linked in wrong order
  2000-05-09 15:04   ` H . J . Lu
@ 2000-05-15  4:07     ` nicola
  2000-05-15 13:00       ` Jeffrey A Law
  0 siblings, 1 reply; 16+ messages in thread
From: nicola @ 2000-05-15  4:07 UTC (permalink / raw)
  To: hjl; +Cc: egcs, ovidiu

> > 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.
> >

Thank you very much for the diagnosis.  My conclusions were similar, but
having a word from someone experienced in the field helps a lot. :-)

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

While I wouldn't use the patch, I am very impressed that you tried
to help that way.  It was really great.

I have solved my problem in a different way.

The problem arises because I patched libobjc to be compiled as shared
library using libtool (patches submitted already but stuck because of the
copyright assignment taking long to be processed).

At this point, I of course want to use the new shared libobjc with
GNUstep.  What happens is that libobjc is providing a minimal
implementation of the class NXConstantString, so that you can compile
trivial Objective-C stuff with libobjc only; but GNUstep is overriding
NXConstantString with a much more complete and powerful implementation,
fully integrated in the GNUstep framework.  (NB: GNUstep's
NXConstantString has a different place in the classes' hierarchy than
libobjc's one).

During the link stage, we want GNUstep's implementation and not libobjc's
one to be used.  This worked till libobjc was static. It doesn't plainly
work with a shared libobjc (as far as I know, this is the only problem we
have).

Actually in the end it probably looks like a very specific problem - I
know no other case in which an objective C library would need to
completely override the implementation of a class in another objective C
library, at the same time moving the class to a different position in the
class hierarchy (what we need to do with NXConstantString).  This is
because usually Objective-C already provides so many ways to
implement/override other classes implementations, that it is rarely needed
to do something of this kind.  I think it's not worth to try having the
runtime load an implementation over another one - causing problems.

So - an ad hoc solution is probably appropriate.

A good idea would simply be not to link in the NXConstantString
implementation in the shared libobjc.  I know people who like this idea a
lot.  My opinion is that this would not allow people to run objective-C
code without linking to GNUstep or another library providing an
implementation of NXConstantString - and we don't want to scare newcomers,
so my proposal is to use the following patch to libobjc/init.c:

--- /home/nicola/egcs-20000424/libobjc/init.c	Mon Jun 21 05:41:41 1999
+++ ./init.c	Wed May 10 13:15:18 2000
@@ -26,6 +26,14 @@

 #include "runtime.h"

+/* This can be overriden with a function returning 1.
+   In that case, libobjc does not load its own version of NXConstantString */
+int
+_user_defined_NXConstantString (void)
+{
+  return 0;
+}
+
 /* The version number of this runtime.  This must match the number
    defined in gcc (objc-act.c) */
 #define OBJC_VERSION 8
@@ -469,7 +477,34 @@
   /* dummy counter */
   int i;

+  /* dummy pointer */
+  const char *p;
+
   DEBUG_PRINTF ("received module: %s\n", module->name);
+
+  if (_user_defined_NXConstantString () == 1)
+    {
+      /* The user has overridden _user_defined_NXConstantString () to
+	 tell us that he doesn't want us to load the library's
+	 NXConstantString implementation */
+      DEBUG_PRINTF ("Filtering out libobjc's NXConstantString at programmer's request:\n");
+
+      /* Search last occurrence of letter 'N' in the module name */
+      p = (char *)strrchr (module->name, 'N');
+      if (p)
+	{
+	  /* Found; compare string starting with this last 'N' to
+	     "NXConstStr_libobjc.m" */
+	  if (strcmp (p, "NXConstStr_libobjc.m") == 0)
+	    {
+	      /* it matches, so it is (should be) our NXConstantString
+                 module - don't load it */
+	      DEBUG_PRINTF ("Module not loaded\n");
+	      return;
+	    }
+	}
+      DEBUG_PRINTF ("Module loaded\n");
+    }

   /* check gcc version */
   init_check_module_version(module);



Then, by patching GNUstep's core/base/NSGCString.m adding the following
lines at the beginning:

/*
 * Newer versions of libobjc require this not to include
 * libobjc's implementation of NXConstantString
 */

int
_user_defined_NXConstantString (void)
{
  return 1;
}

everything works fine: when linking with -lgnustep-base -lobjc, GNUstep's
NXConstantString gets used, while when linking only with -lobjc the
libobjc NXConstantString gets used.

Other libraries different from GNUstep needing to implement their own
NXConstantString instead of the minimal one provided by the Objective C
runtime can do the same using the same trick.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Bug report: objc classes linked in wrong order
       [not found] ` <20000509120515.A18429@lucon.org>
  2000-05-09 12:07   ` H . J . Lu
@ 2000-05-09 15:04   ` H . J . Lu
  2000-05-15  4:07     ` nicola
  1 sibling, 1 reply; 16+ messages in thread
From: H . J . Lu @ 2000-05-09 15:04 UTC (permalink / raw)
  To: nicola; +Cc: egcs

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;
 	}
 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Bug report: objc classes linked in wrong order
       [not found] ` <20000509120515.A18429@lucon.org>
@ 2000-05-09 12:07   ` H . J . Lu
  2000-05-09 15:04   ` H . J . Lu
  1 sibling, 0 replies; 16+ messages in thread
From: H . J . Lu @ 2000-05-09 12:07 UTC (permalink / raw)
  To: nicola; +Cc: GNU C Library, egcs, binutils

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.
> 
> BTW, it may have an impact when libgcc.so is introduced. It will be
> interesting to see the order of calling init if it will make a
> difference.
> 
> 
> H.J.

I forget to include the testcase.

H.J.

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2000-05-30 14:43 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-05-24  7:07 Bug report: objc classes linked in wrong order nicola
     [not found] <20000524102254.A23847@cygnus.com>
2000-05-26  8:38 ` nicola
2000-05-27 15:07   ` Richard Henderson
2000-05-29 10:52   ` Jeffrey A Law
2000-05-30  3:19     ` nicola
2000-05-30  7:50       ` Jeffrey A Law
2000-05-30 10:45         ` nicola
2000-05-30 11:11           ` Helge Hess
2000-05-30 14:43           ` Richard Henderson
  -- strict thread matches above, loose matches on Subject: below --
2000-05-16 11:59 Nick Clifton
     [not found] <Pine.LNX.4.10.10005081510470.23306-101000@lin3.brainstorm.co.uk>
     [not found] ` <20000509120515.A18429@lucon.org>
2000-05-09 12:07   ` H . J . Lu
2000-05-09 15:04   ` H . J . Lu
2000-05-15  4:07     ` nicola
2000-05-15 13:00       ` Jeffrey A Law
2000-05-16  4:08         ` nicola
2000-05-16 16:24           ` Richard Henderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).