This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
Re: How to access application arguments from shared library constructor
- From: "Carlos O'Donell" <carlos at systemhalted dot org>
- To: Mike Frysinger <vapier at gentoo dot org>
- Cc: libc-help at sourceware dot org, Bharath Ramesh <bramesh at vt dot edu>
- Date: Thu, 5 Nov 2009 17:13:05 -0500
- Subject: Re: How to access application arguments from shared library constructor
- References: <20091104221127.GA17565@vt.edu> <200911041809.35232.vapier@gentoo.org>
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?
This code should go under a new "puzzle" section of the glibc wiki.
Please don't loose this gem.
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?
The proper way to do this is with __attribute__((constructor)), but
that doesn't work to solve the problem the user posted.
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.
Cheers,
Carlos.