[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    Re: [PATCH 2/2] arch/{sparc,sparc64}/Makefile: define ARCH_FPIC
From:       Denys Vlasenko <vda.linux () googlemail ! com>
Date:       2017-07-19 16:13:18
Message-ID: CAK1hOcOohPfbwPWEVuFP_HbPyhgABuFU5rkgJ4a54xT1zmQ6bQ () mail ! gmail ! com
[Download RAW message or body]

On Wed, Jul 19, 2017 at 6:01 PM, Denys Vlasenko
<vda.linux@googlemail.com> wrote:
> On Tue, Jul 18, 2017 at 11:40 PM, Thomas Petazzoni
> <thomas.petazzoni@free-electrons.com> wrote:
> > Hello,
> > 
> > On Sat, 15 Jul 2017 14:44:21 +0200, Denys Vlasenko wrote:
> > 
> > > Can you investigate this further?
> > > LIBBUSYBOX build results in entire busybox code being put into a library.
> > > 
> > > nm -D libbusybox.so.1.28.0.git
> > > 
> > > shows that there are only defined entry points to each applet's main():
> > > 
> > > 0007b159 T bunzip2_main
> > > 0007c8db T bzip2_main
> > > 000677bb T cal_main
> > > 0008e08e T cat_main
> > > 
> > > (so, at max less than 350 entry points), and references to libc functions:
> > > 
> > > U asprintf
> > > U atof
> > > U atoi
> > > 
> > > No internal libbb functions or variables are exposed.
> > > 
> > > I don't understand the error messages you are seeing. bb_errno should
> > > have hidden visibility,
> > > meaning that it is an internal (to libbusybox.so) label, and all
> > > references to it
> > > should be resolved without any shared linker magic. .LCn labels are
> > > similar, they are
> > > referring to text strings (messages and such).
> > > 
> > > What is going on? Why your linker has relocations between individual
> > > .o files which go
> > > to the same library?
> > 
> > I'm not really sure what's going on. But the problem can very easily be
> > reproduced:
> > 
> > $ git clone git://git.buildroot.org/buildroot
> > $ cd buildroot/
> > $ cat > .config <<EOF
> > BR2_sparc=y
> > BR2_TOOLCHAIN_EXTERNAL=y
> > BR2_TOOLCHAIN_EXTERNAL_DOWNLOAD=y
> > BR2_TOOLCHAIN_EXTERNAL_URL="http://autobuild.buildroot.org/toolchains/tarballs/br-sparc-uclibc-2017.05-1078-g95b1dae.tar.bz2"
> >  BR2_TOOLCHAIN_EXTERNAL_GCC_6=y
> > BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_1=y
> > BR2_TOOLCHAIN_EXTERNAL_LOCALE=y
> > # BR2_TOOLCHAIN_EXTERNAL_HAS_THREADS_DEBUG is not set
> > BR2_TOOLCHAIN_EXTERNAL_CXX=y
> > BR2_INIT_NONE=y
> > BR2_SYSTEM_BIN_SH_NONE=y
> > BR2_PACKAGE_BUSYBOX_INDIVIDUAL_BINARIES=y
> > # BR2_TARGET_ROOTFS_TAR is not set
> > EOF
> > $ make olddefconfig
> > $ make
> > 
> > It builds only Busybox, so it's very quick to reach the build failure.
> > This time, I got:
> > 
> > libbb/lib.a(appletlib.o): In function `find_applet_by_name':
> > appletlib.c:(.text.find_applet_by_name+0x14): relocation truncated to fit: \
> > R_SPARC_GOT13 against symbol `applet_nameofs' defined in .rodata.applet_nameofs \
> > section in libbb/lib.a(appletlib.o) appletlib.c:(.text.find_applet_by_name+0x18): \
> > relocation truncated to fit: R_SPARC_GOT13 against symbol `applet_names' defined \
> > in .rodata.applet_names section in libbb/lib.a(appletlib.o) \
> > libbb/lib.a(appletlib.o): In function `bb_show_usage': \
> > appletlib.c:(.text.bb_show_usage+0x10): relocation truncated to fit: \
> > R_SPARC_GOT13 against symbol `applet_name' defined in COMMON section in \
> > libbb/lib.a(appletlib.o) appletlib.c:(.text.bb_show_usage+0x54): relocation \
> > truncated to fit: R_SPARC_GOT13 against symbol `bb_banner' defined in \
> > .rodata.bb_banner section in libbb/lib.a(messages.o) libbb/lib.a(appletlib.o): In \
> > function `lbb_prepare': appletlib.c:(.text.lbb_prepare+0x18): relocation \
> > truncated to fit: R_SPARC_GOT13 against symbol `bb_errno' defined in COMMON \
> > section in libbb/lib.a(ptr_to_globals.o) appletlib.c:(.text.lbb_prepare+0x20): \
> > relocation truncated to fit: R_SPARC_GOT13 against symbol `applet_name' defined \
> > in COMMON section in libbb/lib.a(appletlib.o) libbb/lib.a(appletlib.o): In \
> > function `run_applet_no_and_exit': \
> > appletlib.c:(.text.run_applet_no_and_exit+0x28): relocation truncated to fit: \
> > R_SPARC_GOT13 against symbol `xfunc_error_retval' defined in \
> > .data.xfunc_error_retval section in libbb/lib.a(default_error_retval.o) \
> > appletlib.c:(.text.run_applet_no_and_exit+0x38): relocation truncated to fit: \
> > R_SPARC_GOT13 against symbol `applet_name' defined in COMMON section in \
> > libbb/lib.a(appletlib.o) appletlib.c:(.text.run_applet_no_and_exit+0xb0): \
> > relocation truncated to fit: R_SPARC_GOT13 against symbol `applet_main' defined \
> > in .data.rel.ro.applet_main section in libbb/lib.a(appletlib.o) \
> > appletlib.c:(.text.run_applet_no_and_exit+0xcc): relocation truncated to fit: \
> > R_SPARC_GOT13 against symbol `applet_suid' defined in .rodata.applet_suid section \
> > in libbb/lib.a(appletlib.o) appletlib.c:(.text.run_applet_no_and_exit+0x11c): \
> >                 additional relocation overflows omitted from the output
> > collect2: error: ld returned 1 exit status
> > 
> > When I build with my patches (the build is successful), and then look
> > at libbbusybox.so with readelf, the .got section is indeed very small,
> > much smaller than the 8 KB limit detailed in gcc's documentation about
> > -fpic vs. -fPIC:
> > 
> > $ ./output/host/usr/bin/sparc-linux-readelf -a \
> > output/target/lib/libbusybox.so.1.26.2 | grep "\.got" [17] .got              \
> > PROGBITS        000dc000 0cc000 00021c 04  WA  0   0  4 
> > So the size is only 0x21c.
> > 
> > Any idea on how to investigate this further?
> 
> I think what happens is compiler does not know where applet_names[] are,
> assumes it's in another library and generates a reloc.
> Then, the "short" fpic reloc does not work at link time.

With -fPIC:

00013cc4 <find_applet_by_name>:
   13cc4:    9d e3 bf a0     save  %sp, -96, %sp
   13cc8:    2f 00 03 50     sethi  %hi(0xd4000), %l7
   13ccc:    40 00 02 2d     call  14580 <__sparc_get_pc_thunk.l7>
   13cd0:    ae 05 e3 34     add  %l7, 0x334, %l7    ! d4334 <cpdext+0xd>
   13cd4:    39 00 00 92     sethi  %hi(0x24800), %i4   <== applet_nameofs
   13cd8:    b8 1f 3e 28     xor  %i4, -472, %i4        <== applet_nameofs
   13cdc:    b6 10 27 b8     mov  0x7b8, %i3
   13ce0:    b8 05 c0 1c     add  %l7, %i4, %i4
   13ce4:    03 00 00 5a     sethi  %hi(0x16800), %g1   <== applet_names
   13ce8:    82 18 7c bb     xor  %g1, -837, %g1        <== applet_names
   13cec:    fa 17 20 0c     lduh  [ %i4 + 0xc ], %i5
   13cf0:    b4 05 c0 01     add  %l7, %g1, %i2
   13cf4:    90 10 00 18     mov  %i0, %o0
   13cf8:    ba 07 40 1a     add  %i5, %i2, %i5
   13cfc:    40 03 54 17     call  e8d58 <strcmp@plt>

Static build:

00013c54 <find_applet_by_name>:
   13c54:    9d e3 bf a0     save  %sp, -96, %sp
   13c58:    37 00 02 dc     sethi  %hi(0xb7000), %i3  applet_nameofs
   13c5c:    35 00 03 14     sethi  %hi(0xc5000), %i2  applet_names
   13c60:    b6 16 e3 6c     or  %i3, 0x36c, %i3       applet_nameofs
   13c64:    b8 10 27 b8     mov  0x7b8, %i4
   13c68:    b4 16 a1 ff     or  %i2, 0x1ff, %i2       applet_names
   13c6c:    fa 16 e0 0c     lduh  [ %i3 + 0xc ], %i5
   13c70:    90 10 00 18     mov  %i0, %o0
   13c74:    ba 07 40 1a     add  %i5, %i2, %i5
   13c78:    40 03 1b be     call  dab70 <strcmp@plt>

I think what happens is, with static build, linker uses different relocs,
because it knows it will be allowed to edit text segment when binary gets build.

For library, it uses relocs which allow library's text to stay unchanged
when it is linked against other libraries.

What linker does not know is that applet_names[] is in _this_ library.
Need to find a way to tell it that.
_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic