I built our application and a few 3rd party libraries our application
loads with Sun C++ 5.10 SunOS_i386 on two Solaris 10 boxes, one of
which is running on physical Intel and another one is a virtual
Solaris on Intel.
All shared libs have been built with -Kpic or -KPIC. I also specifie -
library=stlport4 option. Nevertheless I receive the following error on
the application start up:
ld.so.1: Exec: fatal: relocation error: R_AMD64_PC32: file Exec:
symbol __1cHCGenVar4nJCData__2t6M_v_: value 0xfffffd7ffc372c4e does
not fit
I found numerous posts regarding this error popping up when building
with Sun C++ running the application on AMD64, but our boxes are
Intel.
Any advise will be appreciated.
Thanks,
Alona
The "R_AMD64_PC32" relocation is used when a 32-bit PC-relative
offset is required when running in long mode (64-bit mode). This
originally applied to the AMD Opteron, which is why the AMD64 is
in the relocation name, but the AMD64 symbols are also used on
Intel x86 family processors when running in long (64 bit) mode.
What it means is that the distance beween the symbol and the code
which is referencing the symbol exceeds the magnitude of a 32-bit
signed integer (2 to the 31st power).
This is likely because the symbol being referenced (__1cHCGenVar4nJCData__2t6M_v_)
which may be a mangled C++ name for a virtual table (through which the code will
indirectly branch to call virtual functions associated with the class) is located
in the .data section and the linker has laid out the code and data sections more
than 2GB apart (which is typical when you have a 64-bit address space).
The value 0xfffffd7ffc372c4e is less than -2^31.
I don't believe we have enough information to determine why this is happening.
I suppose you could run 32-bit solarisx86 instead of 64-bit, so long as you don't
need the large address spaces. You'd need to recompile your apps and libraries
in 32-bit mode (which solaris may allow even when running 64-bit solaris, you
should try this). I guarantee you won't see this relocation error on 32-bit
systems :-)
scott
>The value 0xfffffd7ffc372c4e is less than -2^31.
>I don't believe we have enough information to determine why this is happening.
>I suppose you could run 32-bit solarisx86 instead of 64-bit, so long as you don't
>need the large address spaces. You'd need to recompile your apps and libraries
>in 32-bit mode (which solaris may allow even when running 64-bit solaris, you
>should try this). I guarantee you won't see this relocation error on 32-bit
>systems :-)
There is only one version of Solaris; a version which boots the
system with the appropriate "bitness" (64 bit on 64-bit capable hardware).
The 64 bit kernel will execute both 32 and 64 bit binaries; the compiler
will, by default, create 32 bit binaries.
Casper
--
test
tried compiling without PIC?...
> I found numerous posts regarding this error popping up when building
> with Sun C++ running the application on AMD64, but our boxes are
> Intel.
>
> Any advise will be appreciated.
>
sounds like a compiler bug...
basically, what is going on here is related how the x86-64 instruction
set is implemented:
RIP-relative 32-bit offsets are used for most direct memory operations
(calls, jumps, loads, stores, ...).
whereas, the address space is itself 64-bits (allowing for out-of-range
addresses).
the result is that if a direct call/jump/... is used which only accepts
a 32-bit offset, but the target is outside a +-2GB window, well then,
there is a problem (the address can't fit into the offset).
it is generally the responsibility of the compiler or linker to deal
with this limitation.
the usual strategy (for a compiler) then is to load a 64-bit address
into a register, and then access memory indirectly this way. this is
usually done if the window can't be ensured (say, the code might not be
in the same library).
generally, the most direct way to do this (a 64-bit "mov reg, imm"
operation) would result in an ABS64 relocation.
a variant of the above (used on ELF-based systems) is known as a GOT
(Global Offset Table), or sometimes called PLT (Program Linkage Table),
which is basically a big table holding the addresses of various
variables and/or functions, with operations working by loading the
address from the GOT and then using the loaded address for the operation.
on x86-64, this would consist mostly of using a relative 32-bit load to
fetch the 64-bit address from the GOT. technically, this should work
fine under the (generally sane) assumption that a given library is
itself under 2GB.
another variation on the above is for the linker to insert "trampolines"
(one makes a 32-bit relative call to an indirect 64-bit jump) in the off
case of potentially out-of-range calls/jumps (sadly, this doesn't really
work for variables or similar).
(technically, Windows uses a variant on the trampoline style).
...
but, in any case, this problem should not be taking place if the
compiler were doing its job.
or such...