gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Multiple _OBJC_Module in the same shared library/framework, not so g


From: Nat!
Subject: Re: Multiple _OBJC_Module in the same shared library/framework, not so good
Date: Sat, 7 Jan 2012 16:19:03 +0100

I looked a little more in depth in how things work with respect to the linker, 
and the way objc is tied into it. I thought that the objc baseline would be 
ELF, with some defined objc section types, but it really isn't. Its a little 
more primitive than I imagined. That is good, on the basis, that it works 
everywhere. 

So why do I still care (and yes its still a linker problem :) ) ?

To me +load is crucial and if truely the only guarantee there is, is, that I 
can call some C code, it would be one of this moments in time, where I consider 
tossing the whole objc system and go with a different approach. For most people 
I surmise, the appeal of objc is different then mine. To me the main strength 
of it is systems building, meaning I can structure lots of code in multiple 
conceptual layers (akin to the ISO network model), but I do not end up with a 
monolithic block of code.

Why is +load crucial ? +load is a convenient initialization place, when you are 
mixing C/ObjC and you can't guarantee that +initialize is called before the 
C-code. You can use it for augmenting categories, where the +load method 
initializes some stuff. Also it should be a reliable way to patch third-party 
objc libraries one links against. Not having the last capability means, that 
you are possibly maneuvering yourself in a dead-end (on the objc level). 

A +load with only the most minimal semantic guarantees is therefore useless to 
me.

So lets see what we have. In the simple C case

main.o:  main(){ b(); }
b.so  :  b() { a(); } 
a.so  :  a() {} 

I would have thought, because of the dependencies, that the library 
initializers in a.so must run first then b.so then main.o. (This would imply, 
that classes get +load in a.so before b.so.) The dependencies are noted by the 
linker and the objects are ordered an initialized this way. Ha! That's the way 
it works on OS X, but in Linux the linker doesn't care and just links.

When you link main.o a.o b.o on Linux the initializers being called are 
dependent on the link order (main being last though). Most of the linking 
logic, it seems, is deferred to the runtime linker ld-linux.


My technical solutions are:

a) hack the mainline objc runtime, to delay all +load calls, then sort them 
appropriately and call them on the first +initialize ever. (This may be too 
surprising to some code, which may expect certain functionality not to have run 
already or other initializers that trigger objc code. May have political 
obstacles.)

b) deal with the linking order as is, getting bugs whenever ld-linux changes. 
(That's OK short term, but not in the long run)

c) hack ld-linux.so in some way to get the right initializer order in some sort 
of dependencies and get it accepted into mainline. (Doesn't work for non-linux, 
there may be political obstacles)

d) always link against my custom ld-linux.so. (A pain to maintain)

e) do all the loading myself with <dlfcn.h> and a minimal custom booter (I am 
actually doing something like this already on OS X too, because of Rosetta :( )

so my "app" could actually just look like this:

#!/usr/local/bin/mulle-dyld
a.so
b.so
main.so

Being in control of the linking enables some nice other options...


Another principal problem with solutions a) and c) is, that I think hacks to 
mainline code take years to move to the majority of distributions and installed 
systems. 

So it looks for me like b) then e). But I am open to suggestions. :)

Nat!
---------------------------------------------------
Ich habe überhaupt keine Hoffnung mehr in die 
Zukunft unseres Landes, wenn einmal unsere Jugend
die Männer von morgen stellt. Unsere Jugend ist 
unerträglich, unverantwortlich und entsetzlich 
anzusehen. -- Aristoteles






reply via email to

[Prev in Thread] Current Thread [Next in Thread]