Bug 49286 - LTO incompatible with PIC and inline asm
Summary: LTO incompatible with PIC and inline asm
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: lto (show other bugs)
Version: 4.6.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-06-05 09:23 UTC by Emil Langrock
Modified: 2011-06-05 13:50 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Minimal example (161 bytes, text/x-csrc)
2011-06-05 09:23 UTC, Emil Langrock
Details
Minimal example with fix (203 bytes, text/x-csrc)
2011-06-05 13:50 UTC, Emil Langrock
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Emil Langrock 2011-06-05 09:23:04 UTC
Created attachment 24435 [details]
Minimal example

I have a library which needs to be compiled as PIC (amd64). It has different parts which cannot be written in C and thus uses inline assembly. Other parts can benefit extremely by using LTO (~10% faster and ~10% size reduction). By default it is compiled using something like that:


$ gcc -g -O2 -fPIC -DPIC -o test.o -c test.c
$ gcc -fPIC -shared test.o -o test.so

This works perfectly. It will produce an PIC error when compiling it with LTO:


$ gcc -flto -g -O2 -fPIC -DPIC -o test.o -c test.c
$ gcc -flto -g -O2 -fPIC -DPIC -shared test.o -o test.so
/usr/bin/ld: /tmp/ccMYQCew.ltrans0.ltrans.o: relocation R_X86_64_PC32 against undefined symbol `evil_long' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: ld returned 1 exit status


To the version I use:

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6.1/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.6.0-11' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++,go --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-multiarch --with-multiarch-defaults=x86_64-linux-gnu --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.1 20110604 (prerelease) (Debian 4.6.0-11) 
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.6.1/:/usr/lib/gcc/x86_64-linux-gnu/4.6.1/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.6.1/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.6.1/:/usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/4.6.1/collect2 --build-id --no-add-needed --eh-frame-hdr -m elf_x86_64 --hash-style=both -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../../lib/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../../lib/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.6.1/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.6.1 -L/usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../.. --version -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.6.1/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../../lib/crtn.o
collect2 version 4.6.1 20110604 (prerelease) (x86-64 Linux/ELF)
/usr/bin/ld --build-id --no-add-needed --eh-frame-hdr -m elf_x86_64 --hash-style=both -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../../lib/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../../lib/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.6.1/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.6.1 -L/usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../.. --version -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.6.1/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../../lib/crtn.o
GNU ld (GNU Binutils for Debian) 2.21.51.20110523
Copyright 2011 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty
Comment 1 Jan Hubicka 2011-06-05 11:55:22 UTC
The problem is that GCC do not see that evil_long is used by the asm statement.
Static variables are renamed (in order to produce single .s file you can't have
two different statics with the same name) and then the problem is misdiagnozed
as external reference.

Make evil_long as output of the asm. I.e. something like
asm volatile ("mov %%rsp, $1"::"=m"(evil_long));

All variables accessed by asm statements in direct way (that is w/o the constraints)
must be public and decorated with __attribute__ ((externally_visible))

Honza
Comment 2 Emil Langrock 2011-06-05 11:59:24 UTC
Ok, thanks for the explanation. Sounds reasonable and makes this bug report invalid
Comment 3 Emil Langrock 2011-06-05 13:50:31 UTC
Created attachment 24436 [details]
Minimal example with fix