Bug 30153

Summary: -fPIC failure
Product: gcc Reporter: M Welinder <terra>
Component: targetAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED INVALID    
Severity: normal CC: gcc-bugs, price, reza.yazdani
Priority: P3    
Version: 4.1.0   
Target Milestone: ---   
Host: x86_64-suse-linux Target: x86_64-suse-linux
Build: x86_64-suse-linux Known to work:
Known to fail: Last reconfirmed:

Description M Welinder 2006-12-11 19:24:46 UTC
> cat gcc.c
static inline void foo (void) { }
void baz (void (*f) (void));
void bar (void) { baz (foo); }

> gcc -O0 -c -fPIC gcc.c
> gcc -shared -o gcc.so gcc.o
/usr/lib64/gcc/x86_64-suse-linux/4.1.0/../../../../x86_64-suse-linux/bin/ld: gcc.o: relocation R_X86_64_PC32 against `foo' can not be used when making a shared object; recompile with -fPIC
/usr/lib64/gcc/x86_64-suse-linux/4.1.0/../../../../x86_64-suse-linux/bin/ld: final link failed: Bad value
collect2: ld returned 1 exit status


Note: Adding -02 to the compilation silences this.
Note: Removing "inline" silences this.
Comment 1 Andrew Pinski 2006-12-24 04:49:01 UTC
As far as I can tell this is really a binutils issue.
the difference between static inline and just static is where foo is emitted.  In the static inline case, it is emitted after bar.
Comment 2 price 2007-05-17 03:19:00 UTC
This is also a problem on my amd64 Gentoo laptop, using gcc version Gentoo 4.1.1-r3.

I searched the binutils Bugzilla, but could not find a bug filed for this problem.

Because the problem disappears when optimisation is turned on, the following line from the docs for gcc caught my eye: "GCC does not inline any functions when not optimizing unless you specify the `always_inline' attribute for the function".  So I tried:

price@neverland:/home/price/test>cat static_inline.c 
static void foo (void) __attribute__((always_inline));
static inline void foo (void) { }
void baz (void (*f) (void));
void bar (void) { baz (foo); }
price@neverland:/home/price/test>gcc -O0 -g -c -fPIC static_inline.c
price@neverland:/home/price/test>gcc -shared -o static_inline.so static_inline.o 
/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.1/../../../../x86_64-pc-linux-gnu/bin/ld: warning: creating a DT_TEXTREL in object.
/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.1/../../../../x86_64-pc-linux-gnu/bin/ld: static_inline.o: relocation R_X86_64_PC32 against `foo' can not be used when making a shared object; recompile with -fPIC
/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.1/../../../../x86_64-pc-linux-gnu/bin/ld: final link failed: Bad value
collect2: ld returned 1 exit status


Should I take this bug over to binutils?
Comment 3 Reza Yazdani 2010-02-05 21:10:57 UTC
"The optimization performed is correct because:

In C++ (not in C) a const modifier in a global variable has internal
linkage (i.e. it is treated like a static variable) and therefore the
optimization performed is correct. A global const variable can have
legally different values in different files.

In C, it is illegal to initialize a global variable in more than one
location, and if initialized in more than one place all values must be
the same, because its initial value is nondeterministic if different.

This bug is unrelated to PIC, it will behave the same, if the program is
written according to the C/C++ standards."

I suggest to be closed and marked as user error.
Comment 4 Reza Yazdani 2010-02-05 23:11:01 UTC
(In reply to comment #3)
> "The optimization performed is correct because:
> 
> In C++ (not in C) a const modifier in a global variable has internal
> linkage (i.e. it is treated like a static variable) and therefore the
> optimization performed is correct. A global const variable can have
> legally different values in different files.
> 
> In C, it is illegal to initialize a global variable in more than one
> location, and if initialized in more than one place all values must be
> the same, because its initial value is nondeterministic if different.
> 
> This bug is unrelated to PIC, it will behave the same, if the program is
> written according to the C/C++ standards."
> 
> I suggest to be closed and marked as user error.
> 

Sorry, ignore the above comment. I wanted to add the above comment to the bug 35501. It was the first time I was doing this and somehow, it got added to this bug. Please ignore it.
Comment 5 Andrew Pinski 2011-12-22 02:33:02 UTC
It works with:
GNU assembler (GNU Binutils) 2.22.51.20111217
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 later.
This program has absolutely no warranty.
This assembler was configured for a target of `x86_64-unknown-linux-gnu'.
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/home/pinskia/local-gcc/libexec/gcc/x86_64-unknown-linux-gnu/4.7.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: /home/pinskia/src/local/gcc/configure --prefix=/home/pinskia/local-gcc --enable-languages=all,ada,go
Thread model: posix
gcc version 4.7.0 20111220 (experimental) [trunk revision 182552] (GCC) 

This was a binutils bug which was fixed already.