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.