[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#22430: Relocation error with libstdbuf.so on Solaris SPARC with Stud
From: |
Pádraig Brady |
Subject: |
bug#22430: Relocation error with libstdbuf.so on Solaris SPARC with Studio compilation. |
Date: |
Sun, 24 Jan 2016 09:06:30 -0800 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 |
On 22/01/16 02:28, Rich Burridge wrote:
> Hi,
>
> We've noticed an interesting problem recently with the version of stdbuf
> (really libstdbuf.so) from coreutils version 8.24 on SPARC in Solaris 12.
>
> If you do something like:
>
> $ stdbuf -oL echo
>
> it generates:
>
> ld.so.1: echo: fatal: relocation error: file /usr/lib/64/libstdbuf.so:
> symbol
> program_name: referenced symbol not found
> Killed
>
> but that same command works just fine for stdbuf and libstdbuf.so from
> 8.24 in Solaris 12 on x86.
>
> There's a similar problem for the 32-bit version as well. I'll use that
> to describe what's going on.
>
> I took the command we use to compile 32-bit libstdbuf.c on SPARC:
>
> $ /ws/on12-tools/SUNWspro/solarisstudio12.4/bin/cc -I.
> -I/builds/richb/22510525-coreutils/components/coreutils/coreutils-8.24
> -I./lib -Ilib
> -I/builds/richb/22510525-coreutils/components/coreutils/coreutils-8.24/lib
> -Isrc
> -I/builds/richb/22510525-coreutils/components/coreutils/coreutils-8.24/src
> -I/usr/include/gmp -D_REENTRANT -fPIC -m32 -xO4 -xtarget=ultra2
> -xarch=sparcvis -xchip=ultra2 -Qoption cg -xregs=no%appl -W2,-xwrap_int
> -xmemalign=8s -mt -c -o src/src_libstdbuf_so-libstdbuf.o `test -f
> 'src/libstdbuf.c' || echo
> '/builds/richb/22510525-coreutils/components/coreutils/coreutils-8.24/'`src/libstdbuf.c
>
> and adjusted that to use "-E" instead of "-c" and reran it to generate a
> self-contained lsb.c source file (attached).
>
> I then compiled/linked that on SPARC and x86 (using the commands that are
> generated by our Userland build environment) and noticed the following
> differences:
>
> x86:
>
> $ /ws/on12-tools/SUNWspro/solarisstudio12.4/bin/cc -fPIC -m32 -xO4
> '-xchip=pentium' '-xregs=no%frameptr' -mt -shared -o lsb.so lsb.c
> "src/libstdbuf.c", line 97: warning: shift count negative or too big: << 63
>
> $ elfdump lsb.so | grep program_name
> $
>
> SPARC:
>
> $ /ws/on12-tools/SUNWspro/solarisstudio12.4/bin/cc -fPIC -m32 -xO4
> '-xtarget=ultra2' '-xarch=sparcvis' '-xchip=ultra2' -Qoption cg
> '-xregs=no%appl' -W2,-xwrap_int '-xmemalign=8s' -mt -shared -o lsb.so lsb.c
> "src/libstdbuf.c", line 97: warning: shift count negative or too big: << 63
>
> $ elfdump lsb.so | grep program_name
> [1] 0 0x4 OBJT GLOB D 0 UNDEF program_name
> [42] 0 0x4 OBJT GLOB D 0 UNDEF program_name
> 2 [1] program_name
> [1] 0x1177c 0 R_SPARC_GLOB_DAT program_name
> [12] R_SPARC_GLOB_DAT 0x1177c 0 0 .got program_name
> $
>
>
> Now you can see from lsb.c that the code includes:
>
> extern const char *program_name;
>
> ...
>
> static inline void
> emit_try_help (void)
> {
> fprintf ( ( & __iob [ 2 ] ), gettext ( "Try '%s --help' for more
> information.\n" ), program_name);
> }
>
> It looks like the Studio compiler for x86 is nicely optimizing the
> emit_try_help() away as it's not being used, but the SPARC version of
> the Studio compiler isn't, and is causing the problem.
>
> (Note that this isn't a problem with GNU compiling/linking on Solaris
> for both
> x86 and SPARC).
>
> Now I can "fix" this by adding progname.o (where the program_name variable
> is defined) to libstdbuf.so as it's being linked.
>
>
> $ /ws/on12-tools/SUNWspro/solarisstudio12.4/bin/cc -fPIC -m32 -xO4
> '-xarch=sparcvis' '-xchip=ultra2' '-xregs=no%appl' '-xtarget=ultra2'
> -Qoption cg -W2,-xwrap_int '-xmemalign=8s' -mt -shared -o mylsb.so
> build/sparcv7/lib/progname.o lsb.c
> "src/libstdbuf.c", line 97: warning: shift count negative or too big: << 63
>
> $ elfdump mylsb.so | grep program_name
> [20] 0x11ae4 0x4 OBJT GLOB D 0 .data program_name
> [26] 0x1010 0xf0 FUNC GLOB D 0 .text set_program_name
> [63] 0x11ae4 0x4 OBJT GLOB D 0 .data program_name
> [69] 0x1010 0xf0 FUNC GLOB D 0 .text set_program_name
> [42] 0x1010 0xf0 FUNC GLOB D 0 .text set_program_name
> [36] 0x11ae4 0x4 OBJT GLOB D 0 .data program_name
> [20] program_name
> 26 [26] set_program_name
> [2] 0x11a10 0 R_SPARC_GLOB_DAT program_name
> [23] R_SPARC_HI22 0x10d4 0 0 .text program_name
> [24] R_SPARC_LO10 0x10d8 0 0 .text program_name
> [25] R_SPARC_GLOB_DAT 0x11a10 0 0 .got program_name
>
> but program_name really is an undefined variable here in this context,
> so I was
> wondering if there was a better fix that was needed here.
>
> Thanks in consideration.
>
> PS: Going to bed now; back online in a few hours...
The simplest fix would be to turn it into a macro:
diff --git a/src/system.h b/src/system.h
index 9898bc7..857e56d 100644
--- a/src/system.h
+++ b/src/system.h
@@ -650,11 +650,16 @@ emit_ancillary_info (char const *program)
node, node == program ? " invocation" : "");
}
-static inline void
-emit_try_help (void)
-{
- fprintf (stderr, _("Try '%s --help' for more information.\n"), program_name);
-}
+/* A macro rather than an inline function, as it references
+ the global program_name, which causes run time linking issues
+ in libstdbuf.so where unused functions are not removed by the linker. */
+#define emit_try_help() \
+ do \
+ { \
+ fprintf (stderr, _("Try '%s --help' for more information.\n"), \
+ program_name); \
+ } \
+ while (0)
#include "inttostr.h"