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] | |
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] |