Amd64 relocation R_X86_64_32S in a static lib

Torbjorn Granlund tg at
Tue Nov 5 00:20:53 CET 2013

I am working on getting the GMP bignum library to work better on

With current GMP sources (GMP 5.0.x, 5.1.x, and development head) a
'fat' build will not work on amd64 under OpenBSD 5.3 and 5.4.  With
older version of OpenBSD (I've tested 4.9, 5.0, 5.2) things work as

The problem is related to relocs, in particlar R_X86_64_32S which we use
in a GMP assembly file for 'fat' binaries.

On the problem OpenBSD releases, a fat GMP build end with this error:

libtool: link: gcc -std=gnu99 -O2 -pedantic -fomit-frame-pointer -m64 -o t-bswap t-bswap.o  ./.libs/libtests.a /var/tmp/gmp-obj/hannahobsd64v53-stat-fat/.libs/libgmp.a ../.libs/libgmp.a
/usr/bin/ld: /var/tmp/gmp-obj/hannahobsd64v53-stat-fat/.libs/libgmp.a(fat_entry.o): relocation R_X86_64_32S can not be used when making a shared object; recompile with -fPIC
/var/tmp/gmp-obj/hannahobsd64v53-stat-fat/.libs/libgmp.a: could not read symbols: Bad value

The error message is strange, considering that we certainly are not
"making a shared object".  We are linking a plain object with a static

I have not been able to find any information about what OpenBSD is
trying to do.  But I can discern some dislike for R_X86_64_32S in
OpenBSD 5.3 & 5.4; the bundled gcc typically avoids constructs which
lead to its use, and instead uses GOT relocs.  In older OpenBSD
releases, the construct worked as expected, and the bundled gcc did not
avoid generating R_X86_64_32S (except for PIC code of course).

I consider this a major deviation from the established AMD64 ELF ABI.
It's your decision, and I will not try to make you change your minds.
But I need to understand the decision and how you intend to proceed.  Do
you have a document describing the "AMD64 OpenBSD ABI" with which
developers could comply?

If you don't have such a document, then please help with the present

* Which subset of the AMD64 relocs are to be supported by OpenBSD

* It seems R_X86_64_64 works in non-PIC code such as in the GMP example,
  and while slower than R_X86_64_32S, GMP could use it as a workaround.
  But do you intend to keep that working, or do you intend to completely
  de-support any non-GOT data references?

The last question is motivated by the fact that you seem to have made
gcc use just GOT data references.  That something "seems to work" is not
good enough for me.


More information about the gmp-devel mailing list