Jeremy White wrote:
> 
> [...]
> >
> > It doesn't appear to be able to pass argc and argv until it actually
> > loads the executable start code:
> 
>     Hmm.  We're using different versions; I can't find elf/boot1.c.
> The code I've focused on (from glibc 2.1.3-15):

I was looking at the ld.so / ld-linux.  On a debian machine, do 
an 'apt-get source ldso'.

>     From elf/dl-open.c:  (the _dl_init_next function returns
> the DT_INIT ptr, if any)
> 
>   /* Run the initializer functions of new objects.  */
>   while ((init = _dl_init_next (&new->l_searchlist)))
>     (*(void (*) (int, char **, char **)) init) (__libc_argc,
> __libc_argv,
>                                                 __environ);

So the odd things here are that a) both glibc and ld.so implement 
dlopen - which one is actually being used?  and b) where is glibc
getting __libc_argc and __libc_argv from in the first place.  If 
it's being passed through ld.so, how is that happening given the 
code snippet I posted earlier from ld.so?

The only possibility I can think of is that the ELF AT_ENTRY tag
is only filled by something in glibc, which then takes over some
of the task of dynamic loading after ld.so runs START() - this 
would explain why glibc has the dynamic loader code in it.  I suppose
that the best way to figure out what's actually going on is to 
start playing with debug builds of both ld.so and glibc.

> 
> [...]
> > To further confound things though, when I actually tried making
> > a simple shared lib with an _init function, it *did* get argc
> > and argv, but as you suggested, libc then went wonky because
> > it didn't get initialized properly - note the line above that reads:
> 
> Now, that's odd, because I've just rerun through my samples,
> and everything seems to work as I expected (I can do a getenv(),
> which seems to be a good litmus test).  I did notice when testing
> with Wine that I had to go to some extreme lengths to
> prevent libc from being loaded ahead of Wine (as reported by ldd),
> which does cause disastrous results (but it always does).

My test essentially consisted of a shared lib, not linked to glibc,
which implemented an _init routine that saved argc/argv and then 
tried to call through to glibc's _init routine, and a small program
linked to the lib with a main() that just walked through the argv
list printing each argument.  It would segfault in printf for 
some reason, regardless of whether I had called glibc's _init 
routine. 

>     I can't agree more!  I keep wishing I could think of a better
> reason than that though.  Alexandre has this annoying habit of
> making decisions based on practical things, rather than either
> your or my high moral standards <g>.

8-)

Another thing that this reminds me of is the discussion over the 
wineserver - for winelib apps that don't expect to be doing lots
of communication across several processes, wouldn't it be nice to 
not have a seperate executable and process for the wineserver?  
For single threaded apps this might allow us to see similar 
performance gains as with the proposed kernel-module wineserver....

 -Gav

-- 
Gavriel State
CEO
TransGaming Technologies Inc.
[EMAIL PROTECTED]

Reply via email to