This is the mail archive of the 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 libraryconstructor

On Thu, Nov 05, 2009 at 06:52:48PM -0400, Mike Frysinger wrote:
> On Thursday 05 November 2009 17:13:05 Carlos O'Donell wrote:
> > On Wed, Nov 4, 2009 at 6:09 PM, Mike Frysinger <> 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").
> > 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".

Thanks for this info, I wrote a small test shared library and I am able
to get access to argc, argv, env and enivron. I tried modifying the
value of argc and contents of argv array. I am able to modify the
contents of the argv array, but not argc. Now I understand, I can not
modify the value of argc. This some what seems to break my use case as
when finally main is called with argc and argv they can break the
application if it checks for the value of argc and doesnt find any value
in argv array. I probably need to find a better way to do initialize my
library without affecting the applications default behavior.



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