[Bug middle-end/83074] Shared object built with `-pie --coverage' hangs forever

2017-11-22 Thread stvar at yahoo dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83074

--- Comment #7 from Stefan Vargyas  ---
> 
> libc.so.6 is a shared library, not a PIE.  It is normally linked with -shared,
> just arranged to have .interp section and a meaningful e_entry in Ehdr.
> PIE is something significantly different, in particular it is the executable,
> albeit position independent, e.g. required to be the first in symbol search
> scope so that its symbols bind locally.
> 

Jakub, thank you very much for your deeply insightful info.

I should have had a look at glibc prior to using the `-pie' hackery
for to achive the desired result of running 'foo.so' by itself.

The right solution (at least on GNU/Linux ELF platforms) is to rely on
`-shared', `-Wl,--entry' and a proper '.interp' section in the ELF file
built. (E.g. one cannot get rid of the issues seen above implied by
'__libc_csu_{init,fini}'.)

[Bug middle-end/83074] Shared object built with `-pie --coverage' hangs forever

2017-11-21 Thread stvar at yahoo dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83074

--- Comment #6 from Stefan Vargyas  ---
> 
> Don't use --export-dynamic.  This causes __libc_csu_{init,fini} to be shared
> between the objects instead of having a private copy in each object.
> 

Thank you very much Andreas for your deep inside knowledge!

Indeed, as I'll show below, '__libc_csu_{init,fini}' are
the culprits for 'foo.so' blocking at exit after being
loaded in by 'bar':

(1) Build 'foo.so' exactly as before:

  $ make allclean

  $ make GCC=gcc-7.2.0 COVERAGE=yes foo.so

(2) The ELF file obtained has its dynamic symbol table
containing '__libc_csu_{init,fini}', with both symbols
having their binding set to 'STB_GLOBAL' and visibility
to 'STV_DEFAULT':

  $ readelf --dyn-syms foo.so|grep -E 'libc_csu_(init|fini)'
  46: 3540   137 FUNCGLOBAL DEFAULT   14 __libc_csu_init
  49: 3530 2 FUNCGLOBAL DEFAULT   14 __libc_csu_fini

(3) Do some manual patching of the ELF file for to set
binding to 'STB_LOCAL' and visibility to 'STV_HIDDEN':

  $ ghex2 foo.so

  $ readelf --dyn-syms foo.so|grep -E 'libc_csu_(init|fini)'
  46: 3540   137 FUNCLOCAL  HIDDEN14 __libc_csu_init
  49: 3530 2 FUNCLOCAL  HIDDEN14 __libc_csu_fini

Note that I couldn't avoid manually patching 'foo.so'
since none of the linker options seems to be able to
help (neither `--dynamic-list' nor `--version-script').
Couldn't find help using 'objcopy' either: this tool
doesn't want to touch the dynamic symbol table at all!

(4) Now build 'bar' using the patched 'foo.so':

  $ make GCC=gcc-7.2.0 COVERAGE=yes bar

(5) Both 'foo.so' and 'bar' work nicely (not hanging
anymore):

  $ ./foo.so 
  foo.so: version: 0.1

  $ ./bar
  bar: foo.so: version: 0.1

Only one final remark: `-pie' without `--export-dynamic'
still causes '__libc_csu_{init,fini}' to be added to the
dynamic symbol table:

  $ gcc-7.2.0 -I. -fPIC -fvisibility=hidden -c foo.c -o foo.o

  $ gcc-7.2.0 -Wl,-L. -pie foo.o -o foo.so

  $ readelf --dyn-syms foo.so|grep -P 'libc_csu_(init|fini)'
  40: 33f0   137 FUNCGLOBAL DEFAULT   14 __libc_csu_init
  42: 33e0 2 FUNCGLOBAL DEFAULT   14 __libc_csu_fini

[Bug middle-end/83074] Shared object built with `-pie --coverage' hangs forever

2017-11-20 Thread sch...@linux-m68k.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83074

Andreas Schwab  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |INVALID

--- Comment #5 from Andreas Schwab  ---
> $ gcc -Wl,-L. -Wl,--export-dynamic -pie foo.o -o foo.so

Don't use --export-dynamic.  This causes __libc_csu_{init,fini} to be shared
between the objects instead of having a private copy in each object.

[Bug middle-end/83074] Shared object built with `-pie --coverage' hangs forever

2017-11-20 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83074

--- Comment #4 from Jakub Jelinek  ---
(In reply to Stefan Vargyas from comment #3)
> This feature is quite useful in practice -- for example, the
> GNU C library is runnable this way too:
> 
>   $ /lib64/libc.so.6
>   GNU C Library stable release version 2.11.3 (20110527), by Roland McGrath
> et al.
>   ...

libc.so.6 is a shared library, not a PIE.  It is normally linked with -shared,
just arranged to have .interp section and a meaningful e_entry in Ehdr.
PIE is something significantly different, in particular it is the executable,
albeit position independent, e.g. required to be the first in symbol search
scope so that its symbols bind locally.

[Bug middle-end/83074] Shared object built with `-pie --coverage' hangs forever

2017-11-20 Thread stvar at yahoo dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83074

--- Comment #3 from Stefan Vargyas  ---
> 
> Why do you expect you can use a PIE as a shared library?
> 

Well, with `-pie' one can issue 'foo.so' by itself:

  $ ./foo.so
  foo.so: version 0.1

This feature is quite useful in practice -- for example, the
GNU C library is runnable this way too:

  $ /lib64/libc.so.6
  GNU C Library stable release version 2.11.3 (20110527), by Roland McGrath et
al.
  ...

On the other hand, I deem the above use-case to be not that
useful whilest developing a library -- when one may use e.g.
`--coverage'.

Therefore, I myself have no problem with my (real) Makefile
discriminating 'LDFLAGS' as below:

  ifeq (${COVERAGE},yes)
  CFLAGS += --coverage
  LDFLAGS += --coverage -shared
  else
  LDFLAGS += -pie
  endif

[Bug middle-end/83074] Shared object built with `-pie --coverage' hangs forever

2017-11-20 Thread hjl.tools at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83074

--- Comment #2 from H.J. Lu  ---
(In reply to Martin Liška from comment #1)
> Hi.
> 
> Thanks for the report. I isolated the issue and it's related to how
> constructors are called and hang in GCOV is just demonstration of the
> problem.
> 
> Please consider this:
> 
> $ cat foo.c
> __attribute__ ((constructor)) static void
> ctor2 ()
> {
>   static int c2 = 0;
>   __builtin_printf ("ctor2 called\n");
>   if (c2++ != 0)
> __builtin_abort ();
> }
> 
> int
> main (void)
> {
> }
> 
> $ cat bar.c
> __attribute__((constructor))
> static void ctor1() {
>   static int c1 = 0;
>   __builtin_printf ("ctor1 called\n");
>   if (c1++ != 0)
> __builtin_abort ();
> }
> 
> int main(void)
> {
> }
> 
> Then running:
> 
> $ gcc -g -I. -fPIC -c foo.c -o foo.o 
> $ gcc -g -I. -c bar.c -o bar.o 
> $ gcc -Wl,-L. -Wl,--export-dynamic -pie foo.o -o foo.so

Why do you expect you can use a PIE as a shared library?