libgcrypt relocation error on aarch64
Open, HighPublic

Description

I'm building a static libgcrypt v1.8.4 with PIC for aarch64. Linking it to a shared object fails with a relocation error:

/usr/lib/gcc-cross/aarch64-linux-gnu/7/../../../../aarch64-linux-gnu/bin/ld: /home/baccy/workspace/com.github.lua-curl-lua-curlv3/build/raspberry/lua5.1/build_requirements/jonchki/install/dev/lib/libgcrypt.a(cam
ellia-aarch64.o): relocation R_AARCH64_ADR_PREL_LO21 against symbol `_gcry_camellia_arm_tables' which may bind externally can not be used when making a shared object; recompile with -fPIC
/home/baccy/workspace/com.github.lua-curl-lua-curlv3/build/raspberry/lua5.1/build_requirements/jonchki/install/dev/lib/libgcrypt.a(camellia-aarch64.o): In function `_gcry_camellia_arm_encrypt_block':
/var/lib/jenkins/jobs/se.haxx.curl-curl/workspace/build/raspberry/external/libgcrypt/libgcrypt/src/TARGET_libgcrypt/cipher/camellia-aarch64.S:211:(.text+0x0): dangerous relocation: unsupported relocation
/usr/lib/gcc-cross/aarch64-linux-gnu/7/../../../../aarch64-linux-gnu/bin/ld: /home/baccy/workspace/com.github.lua-curl-lua-curlv3/build/raspberry/lua5.1/build_requirements/jonchki/install/dev/lib/libgcrypt.a(cam
ellia-aarch64.o): relocation R_AARCH64_ADR_PREL_LO21 against symbol `_gcry_camellia_arm_tables' which may bind externally can not be used when making a shared object; recompile with -fPIC
/home/baccy/workspace/com.github.lua-curl-lua-curlv3/build/raspberry/lua5.1/build_requirements/jonchki/install/dev/lib/libgcrypt.a(camellia-aarch64.o): In function `_gcry_camellia_arm_decrypt_block':
/var/lib/jenkins/jobs/se.haxx.curl-curl/workspace/build/raspberry/external/libgcrypt/libgcrypt/src/TARGET_libgcrypt/cipher/camellia-aarch64.S:254:(.text+0xc84): dangerous relocation: unsupported relocation
collect2: error: ld returned 1 exit status

The suggested "-fPIC" option is already there.

I'm cross-compiling with gcc v7.3.0 and binutils v2.30 for aarch64 on a standard Ubuntu 18.04 amd64:

baccy@Yakumo2 ~/workspace % aarch64-linux-gnu-gcc --version
aarch64-linux-gnu-gcc (Ubuntu/Linaro 7.3.0-27ubuntu1~18.04) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

baccy@Yakumo2 ~/workspace % aarch64-linux-gnu-ld --version
GNU ld (GNU Binutils for Ubuntu) 2.30
Copyright (C) 2018 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.

The problem disappeared after this patch:

diff -uNr libgcrypt-1.8.4/cipher/camellia-aarch64.S libgcrypt-1.8.4_patched/cipher/camellia-aarch64.S
--- libgcrypt-1.8.4/cipher/camellia-aarch64.S   2017-11-23 19:16:58.000000000 +0100
+++ libgcrypt-1.8.4_patched/cipher/camellia-aarch64.S   2019-03-22 18:06:37.635546976 +0100
@@ -208,7 +208,7 @@
         *      x3: keybitlen
         */

-       adr RTAB1,  _gcry_camellia_arm_tables;
+       ldr RTAB1, =_gcry_camellia_arm_tables;
        mov RMASK, #(0xff<<4); /* byte mask */
        add RTAB2, RTAB1, #(1 * 4);
        add RTAB3, RTAB1, #(2 * 4);
@@ -251,7 +251,7 @@
         *      x3: keybitlen
         */

-       adr RTAB1,  _gcry_camellia_arm_tables;
+       ldr RTAB1, =_gcry_camellia_arm_tables;
        mov RMASK, #(0xff<<4); /* byte mask */
        add RTAB2, RTAB1, #(1 * 4);
        add RTAB3, RTAB1, #(2 * 4);

As aarch64 is a brand-new architecture for me, this is just a guess. Compared to "adr" the "ldr reg, =label" syntax places the label into the nearest literal pool, which seems to help in my case (see here).

Best regards,
Chris

Details

Version
libgcrypt 1.8.4

This looks duplicate of https://dev.gnupg.org/T4317

Can you check if the patch from T4317 work for you?

jukivili claimed this task.

Thank you, it worked.

jukivili triaged this task as High priority.Apr 1 2019, 9:16 PM
jukivili removed jukivili as the assignee of this task.

Ok, good.

I think commit https://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=commit;h=09c27280cc09798d15369b3a143036b7ab5ddd69 should be backported to 1.8 branch of libgcrypt.