https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69271

--- Comment #6 from nsz at gcc dot gnu.org ---
to complete the example here is a test application:

#include <stdio.h>
#include <stdlib.h>
extern char **environ;
int main()
{
        printf("&environ: %p, environ: %p, *environ: %p\n", &environ, environ,
*environ);
        clearenv(); // *environ = 0
        putenv("TEST=1"); // should change environ
        printf("&environ: %p, environ: %p, *environ: %p\n", &environ, environ,
*environ);
}

with correct libc.so:

$ gcc a.c
$ ./a.out 
&environ: 0x6008b0, environ: 0x7fffb9b0b478, *environ: 0x7fffb9b0d651
&environ: 0x6008b0, environ: 0x600020, *environ: 0x400649
$ readelf --dyn-sym -W ./a.out |grep envi
     2: 00000000006008b0     8 OBJECT  WEAK   DEFAULT   19 _environ
     5: 00000000006008b0     8 OBJECT  GLOBAL DEFAULT   19 __environ
     7: 00000000006008b0     8 OBJECT  WEAK   DEFAULT   19 environ
     8: 00000000006008b0     8 OBJECT  WEAK   DEFAULT   19 ___environ

if libc.so is compiled with -flto:

$ gcc a.c
$ ./a.out 
&environ: 0x600850, environ: 0x7fff52af6158, *environ: 0x7fff52af6651
&environ: 0x600850, environ: 0x7fff52af6158, *environ: 0
$ readelf --dyn-sym -W ./a.out |grep envi
     5: 0000000000600850     8 OBJECT  GLOBAL DEFAULT   19 environ

so environ is shared between a.out and libc.so
in the beginning (clearenv worked), but the
address of the symbol (&environ) is different
so changing it in the libc did not have an effect
in the main module (putenv failed).

this might be an issue in the static or dynamic
linker but the difference is observable.

Reply via email to