Amd64 relocation R_X86_64_32S in a static lib

Philip Guenther guenther at
Tue Nov 5 20:51:45 CET 2013

On Tue, 5 Nov 2013, Torbjorn Granlund wrote:
> Philip Guenther <guenther at> writes:
>   Ah, but you are, sorta.  In OpenBSD 5.3, platforms where the compiler and 
>   toolchain support were for robust for it were switched to build PIE 
>   objects and executables by default.  So yes, that object _is_ expected to 
>   be position independent.  c.f. the gcc-local(1) manpage.
>   At least on OpenBSD, the processor will define __PIC__ and __pic__ when 
>   building both PIC _and_ PIE objects, so you can test those to determine 
>   whether the ASM should use position-independent code sequences.
> I am aware of that people have started using "PIE" as a novel term for
> PIC, sometimes with a subtle difference in meaning, sometimes with the
> exact same meaning.  It is however evident that you're making some much
> larger distinction.  Which one?

We give it the same meaning as gcc and its documentation.  For example:

     These options are similar to `-fpic' and `-fPIC', but generated
     position independent code can be only linked into executables.
     Usually these options are used when `-pie' GCC option will be used
     during linking.

>   R_X86_64_64 is safe for use in PIC/PIE code, though I would expect 
>   %rip relative addressing to be more efficient when it's applicable.
> Now I get really confused.  You disallow R_X86_64_32S which is of the 
> type S + A but allow R_X86_64_64 which is also of the type S + A.  That 
> simply makes no sense at all. If you allow R_X86_64_64 in a relocatable 
> executable, that you will need load-time patching, which precludes any 
> sharing.

Yeah, I spoke too broadly: R_X86_64_64 is only okay for relocations in 
writable segments.  The OpenBSD libc has some of those in its .data 
segment, for exmaple.  You're correct that R_X86_64_64 relocations against 
the text segment prevent sharing.

> That's bad.  But then why not allow R_X86_64_32S too?

Because there's no guarantee that the target is within 2GB, as the 
reference may resolve to the symbol in a different shared object which is 
too far away.

> What was the exact decision for the change in 5.3.  Is it spelled out 
> somewhere for me to read?

"Exact decision for the change"?  I'm not sure what you mean by 'decision' 
there.  If you're wondering about the _reason_ for the change (why we did 
it), the answer is so that ASLR is applied not just to the code in shared 
libraries but also the code in executables.  If you're wondering what was 
done to implement the change, the part that seems to be annoying you is 
that in 5.3 the default for gcc is to pass -fpie to the C compiler and 
-pie to the linker.

> Is there some code which will work for all OpenBSD AMD64 releases?
> E.g., can I count on a PLT and GOT always?  I really don't want to
> support many ABIs for one OS, such support tend to be fragile.

Yes, you can.  If you look at libc.a, for example, you'll see it contains 
R_X86_64_GOTPCREL and R_X86_64_PLT32 relocations.  Those work both when 
building a PIE executable and when building a fully static non-PIE 
executable.  In the latter case they are resolved by the linker when 
generating the executable.

Philip Guenther

More information about the gmp-devel mailing list