Re: Fix profiling support in gcc 4.2
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
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
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
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
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
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
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