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
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
Ok, thanks for the explanation. Sounds reasonable and makes this bug report invalid
Created attachment 24436 [details] Minimal example with fix