Re: Non-PIC objects in shared lib still works?

Michael B Allen <ioplex@xxxxxxxxx> writes:

Hi all,

I've been linking a bunch of .a files into one big shared .so which
worked great.

But trying to link on x86_64 I got the following:

relocation R_X86_64_32 against `a local symbol' can not be used when
making a shared object; recompile with -fPIC ...libfoo.a: could not read
symbols: Bad value

I added -fPIC to the necessary Makefiles and appended CFLAGS="-fPIC" to
configure for various packages. Now everthing links fine (but I haven't
tried the code yet - knock on wood).

It makes perfect sense to me that the .o files in the .a archives should
be compiled with -fPIC if they are to be used to build a .so.

But now I'm very curious as to why my code worked *before*.

Can someone explain to me how .o files compiled *without* -fPIC could
be bundled into a .so and used by applications without error?

Shared libs need PIC on x86-64, or more accurately, relocatable code
has to be PIC. This is because a 32-bit immediate address operand
used in the code might need more than 32 bits after relocation. If
this happens, there is nowhere to write the new value. Theoretically,
it would be possible to generate non-PIC code without using the
troublesome 32-bit immediate operands, but to my knowledge no compiler
does this.

Måns Rullgård