openssl: Invalid relocations when linking a static libcrypto to a shared object on Android armv8

When building openssl for Android-armv8 in a static configuration, then linking this library to a .so (with lld), we get two kinds of relocation errors which are related to the asm modules. Below, I’ll describe each error with outputs and the results of my investigation. A patch that fixes both issues will be attached.

First kind: relocation R_AARCH64_PREL64 cannot be used against symbol OPENSSL_armcap_P

Linker output:

ld.lld: error: relocation R_AARCH64_PREL64 cannot be used against symbol OPENSSL_armcap_P; recompile with -fPIC
>>> defined in ../conan/.conan/data/openssl/1.1.1d-1/tamas/openssl_upgrade2/package/ce6abafda4ebbdbdea95402815ce90c422f5c35a/lib/libcrypto.a(armcap.o)
>>> referenced by chacha-armv8.o:(.text+0x20) in archive ../conan/.conan/data/openssl/1.1.1d-1/tamas/openssl_upgrade2/package/ce6abafda4ebbdbdea95402815ce90c422f5c35a/lib/libcrypto.a

ld.lld: error: relocation R_AARCH64_PREL64 cannot be used against symbol OPENSSL_armcap_P; recompile with -fPIC
>>> defined in ../conan/.conan/data/openssl/1.1.1d-1/tamas/openssl_upgrade2/package/ce6abafda4ebbdbdea95402815ce90c422f5c35a/lib/libcrypto.a(armcap.o)
>>> referenced by poly1305-armv8.o:(.text+0x9A0) in archive ../conan/.conan/data/openssl/1.1.1d-1/tamas/openssl_upgrade2/package/ce6abafda4ebbdbdea95402815ce90c422f5c35a/lib/libcrypto.a

ld.lld: error: relocation R_AARCH64_PREL64 cannot be used against symbol OPENSSL_armcap_P; recompile with -fPIC
>>> defined in ../conan/.conan/data/openssl/1.1.1d-1/tamas/openssl_upgrade2/package/ce6abafda4ebbdbdea95402815ce90c422f5c35a/lib/libcrypto.a(armcap.o)
>>> referenced by sha1-armv8.o:(.text+0x1240) in archive ../conan/.conan/data/openssl/1.1.1d-1/tamas/openssl_upgrade2/package/ce6abafda4ebbdbdea95402815ce90c422f5c35a/lib/libcrypto.a

ld.lld: error: relocation R_AARCH64_PREL64 cannot be used against symbol OPENSSL_armcap_P; recompile with -fPIC
>>> defined in ../conan/.conan/data/openssl/1.1.1d-1/tamas/openssl_upgrade2/package/ce6abafda4ebbdbdea95402815ce90c422f5c35a/lib/libcrypto.a(armcap.o)
>>> referenced by sha256-armv8.o:(.text+0xF88) in archive ../conan/.conan/data/openssl/1.1.1d-1/tamas/openssl_upgrade2/package/ce6abafda4ebbdbdea95402815ce90c422f5c35a/lib/libcrypto.a

ld.lld: error: relocation R_AARCH64_PREL64 cannot be used against symbol OPENSSL_armcap_P; recompile with -fPIC
>>> defined in ../conan/.conan/data/openssl/1.1.1d-1/tamas/openssl_upgrade2/package/ce6abafda4ebbdbdea95402815ce90c422f5c35a/lib/libcrypto.a(armcap.o)
>>> referenced by sha512-armv8.o:(.text+0x1108) in archive ../conan/.conan/data/openssl/1.1.1d-1/tamas/openssl_upgrade2/package/ce6abafda4ebbdbdea95402815ce90c422f5c35a/lib/libcrypto.a

This exact error was reported to the llvm bug tracker, but rejected as invalid: https://bugs.llvm.org/show_bug.cgi?id=32518

The recommendation of declaring the symbol as .hidden in each module works and so far doesn’t seem to have ill effects. I don’t know enough about relocations to confirm or deny the statements in the llvm bug tracker, but it does sound convincing.

As a side note, the same symbol has been already .hidden in armv4cpuid.pl for a long time.

Second kind: relocation R_AARCH64_ADR_PREL_LO21 cannot be used against symbol poly1305_blocks

This error only appeared after fixing the first one. Linker output:

ld.lld: error: relocation R_AARCH64_ADR_PREL_LO21 cannot be used against symbol poly1305_blocks; recompile with -fPIC
>>> defined in ../conan/.conan/data/openssl/1.1.1d-1/tamas/openssl_upgrade2/package/ce6abafda4ebbdbdea95402815ce90c422f5c35a/lib/libcrypto.a(poly1305-armv8.o)
>>> referenced by poly1305-armv8.o:(poly1305_init) in archive ../conan/.conan/data/openssl/1.1.1d-1/tamas/openssl_upgrade2/package/ce6abafda4ebbdbdea95402815ce90c422f5c35a/lib/libcrypto.a

ld.lld: error: relocation R_AARCH64_ADR_PREL_LO21 cannot be used against symbol poly1305_emit; recompile with -fPIC
>>> defined in ../conan/.conan/data/openssl/1.1.1d-1/tamas/openssl_upgrade2/package/ce6abafda4ebbdbdea95402815ce90c422f5c35a/lib/libcrypto.a(poly1305-armv8.o)
>>> referenced by poly1305-armv8.o:(poly1305_init) in archive ../conan/.conan/data/openssl/1.1.1d-1/tamas/openssl_upgrade2/package/ce6abafda4ebbdbdea95402815ce90c422f5c35a/lib/libcrypto.a

As you can see, this is a different relocation and it’s also not possible to simply hide the symbols. Luckily, there was again an existing fix in the armv4 implementation:

https://mta.openssl.org/pipermail/openssl-commits/2018-April/019051.html

I basically ported the same solution to the armv8 version (crypto/poly1305/asm/poly1305-armv8.pl). In a nutshell: I created local labels at the same locations as the global symbols; and referenced those in the branch instructions instead of the global symbols. This removed the need for the dynamic relocations. Credits to the original author of that patch for armv4, Andy Polyakov. Applying this fix removed the relocation errors.

Attachments

Config data, as requested in the template: openssl_configdata.txt

Patch containing the above fixes: android_aarch64_relocations_fix.patch.txt - If there is interest, I’m happy to open a PR with this patch.

Lastly, I don’t think this is strictly related, but we have a patch against the configure script to consume the environment more directly instead of detecting stuff: android_use_env.patch.txt - we have a custom toolchain and the heuristics don’t really work.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 13
  • Comments: 20 (6 by maintainers)

Commits related to this issue

Most upvoted comments

Alright, I’ll open a pull request with the changes.

Closing this. Fixed by #13056 and #13218.

Hi,

This should be fixed on both branch 1.1.1 (and incoming release 1.1.1i) and master now.

Cheers, Romain

@SalusaSecondus happy to release it with whatever license helps you get around such restrictions. By default, I usually release my stuff with the MIT license, so let’s say it’s that. Feel free to contact me via email if you need a different one, or a written permission or something (you can find my address in my fork in the commit I made). Corporations 🤦‍♂️

I’m not sure it was noticed

I think the key is that it needs to be noticed by someone who has andorid dev knowledge, which excludes a lot of us, including me. Opening a PR, as suggested above, seems like the right next step.