This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: How to access application arguments from shared library constructor


On Thursday 05 November 2009 17:13:05 Carlos O'Donell wrote:
> On Wed, Nov 4, 2009 at 6:09 PM, Mike Frysinger <vapier@gentoo.org> wrote:
> > On Wednesday 04 November 2009 17:11:28 Bharath Ramesh wrote:
> >> I am trying to access the arguments passed to an application in the
> >> constructor of a shared library. My aim is to prepend the arguments with
> >> certain arguments that I can strip off just before my constructor exits.
> >> This requires that I have access to the argument list passed to the
> >> application in the constructor. I would appreciate any help on this. I
> >> am sorry if this an incorrect mailing list to ask this question. I
> >> thought this might be good place to start off. I would appreciate if I
> >> am copied in the reply as I am not subscribed to this list.
> >
> > $ cat test.c
> > #include <stdio.h>
> > extern char **environ;
> > foo(int argc, char **argv, char **env)
> > { printf("%i, %p, %s, %p, %p\n", argc, argv, *argv, env, environ); }
> > __attribute__((section(".init_array"))) static void *foo_constructor =
> > &foo; main(){}
> >
> > $ gcc test.c && ./a.out foo
> > 2, 0xbfd877f4, ./a.out, 0xbfd87800, 0xbfd87800
> >
> > maybe someone knows of an easier way to get a pointer into the init_array
> > section ...
> 
> This example is sheer genius. I don't know that it works on all targets?

it relies on INIT_ARRAY support which afaik, is required by newer ELF spec and 
should be supported on all Linux arches now

> I did a double take and then realized that you (a) rely on the dynamic
> linker to setup the incoming arguments *before* calling the
> constructors (b) rely on nothing else adjusting the stack between
> calling old-style .init_array constructors and eventually calling
> main. Did I get that right?

that would be true if i did it via the normal init (constructor) function, but 
the ldso calls init functions in the init/preinit arrays with the same 
arguments as the main function.  look at csu/elf-init.c in glibc.  i'm pretty 
sure this is a requirement according to the ELF spec for these init arrays.

> The proper way to do this is with __attribute__((constructor)), but
> that doesn't work to solve the problem the user posted.

nah, that is the executable-specific and single initializer (i.e. ".init").  
it isnt the same as init arrays (i.e. ".init_array").

compare DT_{INIT,FINI} and DT_{PRE,}{INIT,FINI}_ARRAY

> AFAIK there is no portable way to modify the incoming argc, argv, env
> or environ. The position of each of these is target/ABI dependent, and
> may vary for each glibc port.

i'm not sure what the ELF requirements are here -- are you guaranteed a 
pointer to the argv/env storage ?  obviously modifying argc isnt possible 
since that is always passed as an argument, but modifying the array of 
argv/env pointers should "just work".
-mike

Attachment: signature.asc
Description: This is a digitally signed message part.


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