0

I have created a static library (libar.a), which contains a function foo.

I have a shared object (compiled with -fPIC flag) file that calls foo.

If the object file containing foo has a .rodata section (e.g. a call to printf or a string literal), trying to compile the shared object with the static library fails with this error:

relocation R_X86_64_32 against '.rodata' can not be used when making a shared object; recompile with -fPIC /path/to/static/lib/libar.a: error adding symbols: Bad value collect2: error: ld returned 1 exit status

I know I can solve it by using -fPIC to compile my static object, but I try to understand the reason I get this error.

P.S. While looking for it I found that this happens only on 64-bit platforms.

Thanks.

  • In short (I don't have time to research a proper answer, hence only a comment): it's not about the section (`.rodata`), but the type of the relocation (`R_X86_64_32`) that refers to it. If I remember correctly those simple relocations (`_32`) expect an absolute address for a symbol, but an absolute address for the symbol can not be calculated for a PIC object pretty much by definition. When linking things, either everything has to be PIC or nothing. – Art Jan 15 '18 at 14:16
  • Just to explain a bit more. The code generated an instruction to load an absolute value into a register. Like if you have a `printf` with a normal format string, to load the address of the format string to the register. Without PIC the most efficient instruction to use may be "load number X in %Y". The compiler doesn't know the value of X at compile time, but generates a relocation that will compute X at link time. PIC code can not use those instructions since the address will not be know at link time, most likely the instruction used will be "load number X+%Z in %Y" ("%" denotes a register). – Art Jan 15 '18 at 14:24

0 Answers0