This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PIC is wasteful



On 24-06-2011 13:05, Andrew Haley wrote:

What problem are you trying to solve? I don't get it. Why would you want to avoid 32-bit absolute addresses?
Because the linker complains whenever there is a 32 bit absolute
reference in a 64 bit shared object. I guess the .so can be loaded above
the 2G address limit.
Can you show us how you made a 64-bit absolute reference in a shared
object?  I don't quite understand how that could work.  Apart from
anything else, I don't think the x86_64 has instructions to do it.
If you make a C++ class with virtual functions you will get a virtual table. This is a table of function pointers to the virtual functions. The exception handler section also has initialized pointers, including a pointer to __gxx_personality_v0 (whatever that does?) and to destructor code. All these pointers are resolved by the loader when an executable or shared object is loaded. All these pointers are 64 bit in 64 bit mode.

The instruction set has instructions for calling a function through a pointer and for accessing data through a pointer. These pointers must be 64 bit in 64 bit mode. (It also has instructions for reading/writing the ax register with a 64 bit absolute address, but these instructions are rarely used and some assemblers don't support them, but that's another story.)

The purpose of position-independent code is to reduce the number of absolute addresses that the loader has to resolve in order to make loading faster. The flipside of this coin is that addresses need to be calculated at runtime rather than at loadtime. The loadtime address calculations are done only once, while the runtime address calculations may be done an unlimited number of times. This is particularly time consuming in 32 bit x86 code because the 32-bit instruction set has no instructions for self-relative addressing of data.
Apparently, the only way to avoid 32 bit addresses is compiling with
-fpic, which has the undesired effect of using GOT and PLT entries which
makes shared objects slower than static libraries. The seldom used
feature to override a symbol comes at a high price.
Its isn't seldom used. It's used all the time.

If it weren't possible to override symbols in shared libraries, every
user of a library would be forbidden to use any of the symbols exported
by that library in their own programs.
If you declare a symbol as external in the main executable you will access the version in the shared object. This is what you do when calling a library function. This is not overriding. If you make an instance of the symbol in the main executable you will override the version in the shared object. That may be needed for functions (for example overloading the new operator) but rarely for data.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]