So far my code was compiling perfectly in all the platform but after a recent new addition, the compiler gave this error while compiling.
too many symbols require ‘small’ PIC references :
Have 1092, maximum 1024 –recompile some modules –K PIC.
As I researched this. I found my code has hit a rare case event.
KPIC and Kpic compiler options produces position-independent code for use in shared libraries.
Generally the Kpic works fine and does the job, but in rare case Kpic hits the limit and then KPIC has to be used.
What is Position-Independent Code?
The code within a dynamic executable is typically position-dependent, and is tied to a fixed address in memory. Shared objects, on the other hand, can be loaded at different addresses in different processes. Position-independent code is not tied to a specific address.
This independence allows the code to execute efficiently at a different address in each process that uses the code and thus position-independent code is always recommended for the creation of shared objects.
Here’s are the bits that helped me figure this out.
What is -KPIC and -Kpic?
Produces position-independent code for use in shared libraries. Each reference to a global datum is generated as a dereference of a pointer in the global offset table. Each function call is generated in pc-relative addressing mode through a procedure linkage table.
(SPARC) (PowerPC) With this option, the global offset table spans the range of 32-bit addresses in those rare cases where there are too many global data objects for -Kpic.
(Intel) -KPIC is identical to -Kpic.
Produces position-independent code for use in shared libraries.
(SPARC) (PowerPC) It is similar to -KPIC, but the size of the global offset table is limited to 8Kbytes.
Performance costs with -Kpic and -KPIC
There are two nominal performance costs with -Kpic and -KPIC:
A routine compiled with either -Kpic or -KPIC executes a few extra instructions upon entry to set a register to point at a table (_GLOBAL_OFFSET_TABLE_) used for accessing a shared library’s global or static variables.
Each access to a global or static variable involves an extra indirect memory reference through _GLOBAL_OFFSET_TABLE_. If the compile is done with -KPIC, there are two additional instructions per global and static memory reference.
When considering the above costs, remember that the use of -Kpic and -KPIC can significantly reduce system memory requirements, due to the effect of library code sharing. Every page of code in a shared library compiled -Kpic or -KPIC can be shared by every process that uses the library.
If a page of code in a shared library contains even a single non-pic (that is, absolute) memory reference, the page becomes non sharable, and a copy of the page must be created each time a program using the library is executed.
How to tell whether or not an object is compiled with -Kpic or –KPIC?
The easiest way to tell whether or not a .o file has been compiled with -Kpic or -KPIC is with the nm command:
% nm file.o | grep _GLOBAL_OFFSET_TABLE_
A .o file containing position-independent code contains an unresolved external reference to _GLOBAL_OFFSET_TABLE_, as indicated by the letter U.
How to decide what to use -Kpic or –KPIC?
To determine whether to use -Kpic or -KPIC, use nm to identify the number of distinct global and static variables used or defined in the library.If the size of _GLOBAL_OFFSET_TABLE_ is under 8,192 bytes, you can use -Kpic. Otherwise, you must use -KPIC.
Primary Source: cc compiler options
To know more about Global Offset Table click here.