[comp.windows.x] Problem with X Shared Libraries

joan@richsun.UUCP (Joan Siebenaler) (06/13/89)

I've had a problem running programs linked with the X built Shared
Libraries on Sun machines.  The problem is in the Xt code.  When a widget
sets a procedure in it's class record to inherent the parents procedure
the _XtInherit error function is called and exits.

The widget initialization code does a compare of the _XtInherit address
with the value stored in the Widget's class record.  The XtInherit
procedures XtInsertChild, XtInheritResize, XtRealize, etc. are define
as the _XtInherit procedure.  In the widgets class initialization if 
the value stored in the class record is equal to the _XtInherit function
address the widget's parent procedure address is stored in the class
record.  When the Xt library is built as a shared library  the _XtInherit 
address is resolved to a library branch table entry and is not equal to
the value set in the widgets class record.  The conditional branch is not
taken and the widget's parent procedure is not inherited.

To fix this problem I defined all the XtInherit procedures to a constant
and defined _XtInherit equal to the same constant.  This flags the widget 
initialization to inherit the parents procedure and an address comparison
is not done.

Has anyone else out there had this problem.  Should the link editor be able
to resolve the address comparison of a shared library procedure with the 
procedure address stored in the non-shared code, or should address
comparisons not be done.  

Thanks for any help or comments you can give me.
 
Joan Siebenaler   (312) 455-6100, ext 621    uunet!richsun!joan

dshr@SUN.COM (David Rosenthal) (06/14/89)

> I've had a problem running programs linked with the X built Shared
> Libraries on Sun machines.  The problem is in the Xt code.  When a widget
> sets a procedure in it's class record to inherent the parents procedure
> the _XtInherit error function is called and exits.
> 
This problem has already been brought to our attention.  The relevant
expert is examining it - it would appear (at first sight) to be a bug
in SunOS.  I will report again when there is more to say.

	David.

david@sun.com (Spam 'n Bean Burrito) (06/14/89)

In article <389@richsun.UUCP> joan@richsun.UUCP (Joan Siebenaler) writes:
>I've had a problem running programs linked with the X built Shared
>Libraries on Sun machines.  The problem is in the Xt code.  When a widget
>sets a procedure in it's class record to inherent the parents procedure
>the _XtInherit error function is called and exits.
>
>The widget initialization code does a compare of the _XtInherit address
>with the value stored in the Widget's class record.  The XtInherit
>procedures XtInsertChild, XtInheritResize, XtRealize, etc. are define
>as the _XtInherit procedure.  In the widgets class initialization if 
>the value stored in the class record is equal to the _XtInherit function
>address the widget's parent procedure address is stored in the class
>record.  When the Xt library is built as a shared library  the _XtInherit 
>address is resolved to a library branch table entry and is not equal to
>the value set in the widgets class record.

You probably don't want to know this, but the problem is a side effect of
the (default use) of the ld "-dc -dp" flags.  This creates a jump table
for library functions.  Function calls from your program into the shared
libraries are statically bound to stubs in the jump table, which is filled
in later by the run-time linker.  This keeps your text segment pure even
if you don't use -pic.

Anyway, I also ran into this when developing the SunOS 4.0 shared pixrect
library.  After talking to the shared library architect, the best fix I
could come up with was to create a stub function for each library function
with a "public" address, e.g.:

	Given a library function foo, where both application and library
	code reference &foo...

	Rename foo() to _foo().

	Create a stub function foo() which calls _foo() (in a separate
	source file).

	Link the foo stub .o file into the library.so file, *and* add it
	to the library.sa file (create it if you haven't already).

After you do this the foo() stub from the .sa file will be copied into the
application, and both application and library code will agree that &foo is
its address.
-- 
David DiGiacomo, Sun Microsystems, Mt. View, CA  sun!david david@sun.com