Re: Fix profiling support in gcc 4.2

2013-03-26 Thread Pascal Stumpf
On Tue, 26 Mar 2013 21:48:42 +0200, Paul Irofti wrote:
 Good evening everyone,
 
 I discovered about one or two weeks ago that I can't link any debug
 libraries on OpenBSD. At first I thought it was a cmake update[1] but
 then I started digging further and it turns out its our gcc.

This is not about debug, but profiling libraries.

 What threw me off is that gcc-4.7 from ports behaves the same way, but
 I later discovered it's the same issue.
 
 Anyway, the problem pops up when doing something like this:
 
 ---
 $ cc -shared -fpic  -o libtest.so.0.0  `lorder test.so test1.so|tsort -q`
 $
 ---
 
 versus something like this:
 
 ---
 $ cc -shared -fpic  -pg -o libtest.so.0.0  `lorder test.so test1.so|tsort -q`
 /usr/bin/ld: warning: cannot find entry symbol _start; defaulting to
 00400260
 $
 ---
 
 This used to work in the past and no longer does on -current.

It used to work in the sense that it produced a shared library with
profiling and debug information.  But this information is useless on
OpenBSD.  Profiling only works with static executables/libraries.
Adding support for shared libraries would be non-trivial, and probably
need support in ld.so.  Look at sprof on Linux (even there, gprof
doesn't support shared libraries).

The correct approach here is probably to error out when -pg is given in
combination with -shared on OpenBSD.

Have you seen this command line in a real-world build system?  In that
case, just disable -pg.

 I tested on a 5.1 system and the last command links libtest properly
 without an error.
 
 I tracked it down to the commit that enabled PIE support on OpenBSD.
 
 I looked at the specs from other operating systems and Linux
 distributions and I haven't found any -nopie references not only in the
 libs section, but throughout the entire spec.

That's because nobody else has the -nopie option in ld.

 Thus I propose the following diff that removes the nopie bits.

No, this would break linking profiled executables.

 An identical diff is needed for the ports tree and I will take care of
 it if this is accepted. So comments, okays?
 
 Cheers,
 Paul Irofti
 
 
 [1] -- http://marc.info/?l=openbsd-portsm=136371733926696w=2
 
 Index: gcc/gcc.c
 ===
 RCS file: /cvs/src/gnu/gcc/gcc/gcc.c,v
 retrieving revision 1.2
 diff -u -p -r1.2 gcc.c
 --- gcc/gcc.c 28 Aug 2012 18:59:28 -  1.2
 +++ gcc/gcc.c 26 Mar 2013 19:33:05 -
 @@ -684,7 +684,7 @@ proper position among the other output f
  
  #ifndef LINK_PIE_SPEC
  #ifdef HAVE_LD_PIE
 -#define LINK_PIE_SPEC %{pie:-pie} %{p|pg|nopie:-nopie} 
 +#define LINK_PIE_SPEC %{pie:-pie} 
  #else
  #define LINK_PIE_SPEC %{pie:} 
  #endif
 
 



Re: Fix profiling support in gcc 4.2

2013-03-26 Thread Paul Irofti
On Tue, Mar 26, 2013 at 09:15:38PM +0100, Pascal Stumpf wrote:
 On Tue, 26 Mar 2013 21:48:42 +0200, Paul Irofti wrote:
  Good evening everyone,
  
  I discovered about one or two weeks ago that I can't link any debug
  libraries on OpenBSD. At first I thought it was a cmake update[1] but
  then I started digging further and it turns out its our gcc.
 
 This is not about debug, but profiling libraries.

Yes, I know that. As the email subject says. My debug libraries are also
compiled with profiling info.

  What threw me off is that gcc-4.7 from ports behaves the same way, but
  I later discovered it's the same issue.
  
  Anyway, the problem pops up when doing something like this:
  
  ---
  $ cc -shared -fpic  -o libtest.so.0.0  `lorder test.so test1.so|tsort -q`
  $
  ---
  
  versus something like this:
  
  ---
  $ cc -shared -fpic  -pg -o libtest.so.0.0  `lorder test.so test1.so|tsort 
  -q`
  /usr/bin/ld: warning: cannot find entry symbol _start; defaulting to
  00400260
  $
  ---
  
  This used to work in the past and no longer does on -current.
 
 It used to work in the sense that it produced a shared library with
 profiling and debug information.  But this information is useless on
 OpenBSD.  Profiling only works with static executables/libraries.

Well, then perhaps just ignore the option when passed without nopie?

 Adding support for shared libraries would be non-trivial, and probably
 need support in ld.so.  Look at sprof on Linux (even there, gprof
 doesn't support shared libraries).

Interesting, I will, thanks!

 The correct approach here is probably to error out when -pg is given in
 combination with -shared on OpenBSD.
 
 Have you seen this command line in a real-world build system?  In that
 case, just disable -pg.

Yes I did. I've been building this way for three years now.

I would just set something like this, and it would work like a charm:

set (CMAKE_CXX_FLAGS_DEBUG  -O0 -g -pg)
set (CMAKE_CXX_FLAGS_MINSIZEREL -Os -DNDEBUG)
set (CMAKE_CXX_FLAGS_RELEASE-O2 -DNDEBUG)
set (CMAKE_CXX_FLAGS_RELWITHDEBINFO -O2 -DNDEBUG -g)

But now, when I tried to build inside a clean object directory I ran
into this issue.

  I tested on a 5.1 system and the last command links libtest properly
  without an error.
  
  I tracked it down to the commit that enabled PIE support on OpenBSD.
  
  I looked at the specs from other operating systems and Linux
  distributions and I haven't found any -nopie references not only in the
  libs section, but throughout the entire spec.
 
 That's because nobody else has the -nopie option in ld.

Okay.

  Thus I propose the following diff that removes the nopie bits.
 
 No, this would break linking profiled executables.

I don't understand how, can you go into more details please?

Anyway, can we then just ignore the -pg option if it doesn't work for
shared instead of breaking the link? Or do you have a better solution?

Thanks,
Paul Irofti



Re: Fix profiling support in gcc 4.2

2013-03-26 Thread Mark Kettenis
 Date: Tue, 26 Mar 2013 23:54:20 +0200
 From: Paul Irofti p...@irofti.net
 I don't understand how, can you go into more details please?
 
 Anyway, can we then just ignore the -pg option if it doesn't work for
 shared instead of breaking the link? Or do you have a better solution?

Perhaps ld shouldn't set link_info.shared to FALSE when it sees -nopie?



Re: Fix profiling support in gcc 4.2

2013-03-26 Thread Pascal Stumpf
On Tue, 26 Mar 2013 23:54:20 +0200, Paul Irofti wrote:
 On Tue, Mar 26, 2013 at 09:15:38PM +0100, Pascal Stumpf wrote:
  On Tue, 26 Mar 2013 21:48:42 +0200, Paul Irofti wrote:
   Good evening everyone,
   
   I discovered about one or two weeks ago that I can't link any debug
   libraries on OpenBSD. At first I thought it was a cmake update[1] but
   then I started digging further and it turns out its our gcc.
  
  This is not about debug, but profiling libraries.
 
 Yes, I know that. As the email subject says. My debug libraries are also
 compiled with profiling info.
 
   What threw me off is that gcc-4.7 from ports behaves the same way, but
   I later discovered it's the same issue.
   
   Anyway, the problem pops up when doing something like this:
   
   ---
   $ cc -shared -fpic  -o libtest.so.0.0  `lorder test.so test1.so|tsort -q`
   $
   ---
   
   versus something like this:
   
   ---
   $ cc -shared -fpic  -pg -o libtest.so.0.0  `lorder test.so test1.so|tsort 
   -q`
   /usr/bin/ld: warning: cannot find entry symbol _start; defaulting to
   00400260
   $
   ---
   
   This used to work in the past and no longer does on -current.
  
  It used to work in the sense that it produced a shared library with
  profiling and debug information.  But this information is useless on
  OpenBSD.  Profiling only works with static executables/libraries.
 
 Well, then perhaps just ignore the option when passed without nopie?

You probably mean with -shared.  At the moment, -pg implies -nopie at
the linking stage.

  Adding support for shared libraries would be non-trivial, and probably
  need support in ld.so.  Look at sprof on Linux (even there, gprof
  doesn't support shared libraries).
 
 Interesting, I will, thanks!
 
  The correct approach here is probably to error out when -pg is given in
  combination with -shared on OpenBSD.
  
  Have you seen this command line in a real-world build system?  In that
  case, just disable -pg.
 
 Yes I did. I've been building this way for three years now.
 
 I would just set something like this, and it would work like a charm:
 
 set (CMAKE_CXX_FLAGS_DEBUG  -O0 -g -pg)
 set (CMAKE_CXX_FLAGS_MINSIZEREL -Os -DNDEBUG)
 set (CMAKE_CXX_FLAGS_RELEASE-O2 -DNDEBUG)
 set (CMAKE_CXX_FLAGS_RELWITHDEBINFO -O2 -DNDEBUG -g)
 
 But now, when I tried to build inside a clean object directory I ran
 into this issue.

Hmm, okay; but as far as I know, this will *never* produce a shared
library that's actually suitable for being profiled.  Even when using
sprof on Linux, the documentation out there on the net suggests you
should use -g, not -pg.  So, if you actually want to build profiling
(and not just debug) libraries, it takes more build system changes that
just setting CFLAGS to -pg: You need to create a static library with a
_p suffix instead of a shared one.

   I tested on a 5.1 system and the last command links libtest properly
   without an error.
   
   I tracked it down to the commit that enabled PIE support on OpenBSD.
   
   I looked at the specs from other operating systems and Linux
   distributions and I haven't found any -nopie references not only in the
   libs section, but throughout the entire spec.
  
  That's because nobody else has the -nopie option in ld.
 
 Okay.
 
   Thus I propose the following diff that removes the nopie bits.
  
  No, this would break linking profiled executables.
 
 I don't understand how, can you go into more details please?

At the moment, profiling does not have PIC (or PIE) support.  So
everything compiled with profiling is non-PIE (-pg implies -fno-pie when
compiling).  The linker, however, defaults to -pie on all PIE archs.  So
it needs to be told to not try to generate a position-independent
executable when dealing with profiling (which is exactly what the spec
you proposed to remove does) or you end up with could not use
relocation foo when making a shared object errors.

 Anyway, can we then just ignore the -pg option if it doesn't work for
 shared instead of breaking the link? Or do you have a better solution?

I could do that (if I figure out the correct gcc specs), sure.

 Thanks,
 Paul Irofti
 
 



Re: Fix profiling support in gcc 4.2

2013-03-26 Thread Pascal Stumpf
On Tue, 26 Mar 2013 23:05:05 +0100 (CET), Mark Kettenis wrote:
  Date: Tue, 26 Mar 2013 23:54:20 +0200
  From: Paul Irofti p...@irofti.net
  I don't understand how, can you go into more details please?
  
  Anyway, can we then just ignore the -pg option if it doesn't work for
  shared instead of breaking the link? Or do you have a better solution?
 
 Perhaps ld shouldn't set link_info.shared to FALSE when it sees -nopie?

At the ld level, it basically breaks down to the question what the
desired behaviour is when nonsensical combinations of -nopie and -shared
are encountered.  At the moment, -nopie cancels out a previously
encountered -shared, so

ld -shared -nopie ...

will try to generate a non-shared, non-pie object, while

ld -nopie -shared ...

will behave the same as ld -shared.  I think this is the behaviour
most people would expect, but I might be wrong.  Other opinions?



Re: Fix profiling support in gcc 4.2

2013-03-26 Thread Philip Guenther
On Tue, Mar 26, 2013 at 3:45 PM, Pascal Stumpf pascal.stu...@cubes.de wrote:
...
 Anyway, can we then just ignore the -pg option if it doesn't work for
 shared instead of breaking the link? Or do you have a better solution?

 I could do that (if I figure out the correct gcc specs), sure.

Change this:
   %l %{pie:-pie} %{p|pg|nopie:-nopie}

to this:
   %{pie:-pie} %{p|pg|nopie:-nopie} %l

in the link_command spec.

...but I also like Mark's suggestion, to make -nopie not change the
link mode (shared-object vs executable).


Philip Guenther



Re: Fix profiling support in gcc 4.2

2013-03-26 Thread Pascal Stumpf
On Tue, 26 Mar 2013 16:39:54 -0700, Philip Guenther wrote:
 On Tue, Mar 26, 2013 at 3:45 PM, Pascal Stumpf pascal.stu...@cubes.de wrote:
 ...
  Anyway, can we then just ignore the -pg option if it doesn't work for
  shared instead of breaking the link? Or do you have a better solution?
 
  I could do that (if I figure out the correct gcc specs), sure.
 
 Change this:
%l %{pie:-pie} %{p|pg|nopie:-nopie}
 
 to this:
%{pie:-pie} %{p|pg|nopie:-nopie} %l
 
 in the link_command spec.

That would require changing how LINK_PIE_SPEC is integrated into
LINK_COMMAND_SPEC, and it exploits the -nopie/-shared ordering nits I
mentioned, so I'm not a fan of that.  I thought of something like this:

Index: gcc.c
===
RCS file: /home/pascal/cvs/src/gnu/gcc/gcc/gcc.c,v
retrieving revision 1.2
diff -u -p -r1.2 gcc.c
--- gcc.c   28 Aug 2012 18:59:28 -  1.2
+++ gcc.c   26 Mar 2013 23:29:00 -
@@ -684,7 +684,7 @@ proper position among the other output f
 
 #ifndef LINK_PIE_SPEC
 #ifdef HAVE_LD_PIE
-#define LINK_PIE_SPEC %{pie:-pie} %{p|pg|nopie:-nopie} 
+#define LINK_PIE_SPEC %{pie:-pie} %{!shared:%{p|pg:-nopie}} %{nopie:-nopie} 
 #else
 #define LINK_PIE_SPEC %{pie:} 
 #endif

 ...but I also like Mark's suggestion, to make -nopie not change the
 link mode (shared-object vs executable).
 
 
 Philip Guenther