PIC is wasteful
Andrew Haley
aph@redhat.com
Thu Jun 23 17:43:00 GMT 2011
On 06/23/2011 04:06 PM, Agner Fog wrote:
> On 23-06-2011 15:53, Andrew Haley wrote:
>> On 06/23/2011 02:35 PM, Agner Fog wrote:
>>> Question 3:
>>> ----------------
>>> When I make a self-relative reference to a public variable in a 64-bit
>>> .so I get the linker error:
>>> relocation R_X86_64_PC32 against `VariableName' can not be used when
>>> making a shared object; recompile with -fPIC
>>> This message is illogical because the reference is indeed
>>> position-independent. It appears only when the variable is public, not
>>> when it is local.
>> Think about what happens if the executable defines that same symbol.
>> If that happens, all references to that symbol must refer to the
>> same location in the executable.
>>
> Thank you for the explanation. That makes sense. But I would expect the
> linker to make an error message if two symbols have the same name. Why
> does a GOT entry solve the problem - you still have two symbols with the
> same name? The GOT should be transparent to the C/C++ programmer.
The runtime linker (ld.so) fixes up all GOT entries to point to the
same memory location.
>>> Apparently, gcc avoids the problem by using a GOT
>>> entry when the variable is public. I can solve the problem in assembly
>>> by giving the variable two names, one public and one local, and making a
>>> relative reference to the local name.
>>> Why does gcc not use the same trick?
>> Because it's broken: there can only be one instance of a symbol X in
>> a running program, and every reference to X must refer to the same
>> memory.
> It's not broken. Just apply two names to the same memory location (gas
> syntax):
> .globl name1
> name1:
> name2:
> .string "This text string has two names"
That doesn't help. It's broken because the reference to X in the
shared library points to a different X from the reference to X in
the executable.
The C standard says that if you take the address of a variable X
in a a library:
my_pointer foo = &X;
and if you do the same thing in the executable:
my_pointer bar = &X;
then
foo == bar
The key here is that the executable is allowed to redefine symbols
that exist in libraries.
Andrew.
More information about the Gcc-help
mailing list