3

Problem: I need to port gnutls to Android to be used in a shared library (say library A) I'm using in my Android application.

What I've tried: I've modified the make file for openconnect to generate a .a static library file for gnutls and its dependencies (libgmp, libnettle and libhogweed), I used them to build static libraries in my Android project and referenced them in the shared library A. Code builds and installs fine but on M+ devices I get the following error at runtime:

java.lang.UnsatisfiedLinkError: dlopen failed: libA.so: has text relocations

I've tried to pass the -fPIC flag when building the static libraries (.a files) and when building the libA.so file with no luck, I can always see TEXTREL entries in libA.so file. I'm sure it is due to the those new static libraries since I was using libA before with no issues. Other thing I tried: tried building gnutls as a shared library, the generated libA.so now had no text relocations but would still fail to load at runtime because the gnutls so files have a version (e.g libgnutls.so.3.0) and Android does not support versioned libraries.

Specific question: How can I either: 1.Build gnutls as a static library without text relocations or 2. Build it as a shared library with no soname?

Edit: I see the same question asked on the openconnect mailing list but no clear way on how to "fix the TEXTRELs in the native code first".

I have seen other answers for problems with text relocations like this question and this question but that didn't help since I'm using the latest NDK build and passing the PIC flag already

Community
  • 1
  • 1
Nonos
  • 2,327
  • 2
  • 20
  • 33
  • 1
    Possible duplicate of [libavcodec.so: has text relocations](http://stackoverflow.com/questions/32346402/libavcodec-so-has-text-relocations) – Richard Critten Aug 30 '16 at 16:59
  • I don't think it's a duplicate because I'm using the latest NDK to build and also passing the -fPIC flag to build a position independent code – Nonos Aug 30 '16 at 17:03
  • It really is the same problem as in question mentioned by @RichardCritten, have a look at "Text Relocations (Enforced since API 23)" section of [this page](http://android-developers.blogspot.ru/2016/06/android-changes-for-ndk-developers.html), although the accepted answer on that question is just a workaround, the real thing is to fix the library, but that's library-specific (starting with the fact that you have four of them combined) and dependant on options you use to build it. – Roman Khimov Sep 02 '16 at 08:42
  • It may be the same problem but the only solutions given there is either the workaround you mentioned which is not an option since I'm targeting, or to build the libraries with the -fPIC flag which I've done already. – Nonos Sep 02 '16 at 13:54

2 Answers2

1

You can't load a library that requires Text Relocations:

Starting with API 23, shared objects must not contain text relocations. That is, the code must be loaded as is and must not be modified.

(source)

Answers:

How can I build gnutls as a static library without text relocations?

-fPIC can't prevent all text relocation. In some cases, if your library uses inline asm, the compiler will unable to make it Position Independent (PIC). However, if you sure your library can be position independent, the problem may be a somewhere in your build config.

If not, you should prevent your library from using text Relocations. Fortunately, there is a great wiki page that explains how to do that in the Gentoo Wiki.

How can I build it as a shared library with no soname?

You can set your soname with: gcc -shared -Wl,-soname,your_soname.

Shmuel H.
  • 1,840
  • 1
  • 13
  • 26
  • I'm sorry but this answer just states the question again ... Note that I detailed the problem in the question and that I understand what the symptoms are but the answers given to similar questions did not help in my case, more specifically I stated that I did build with -fPIC which should prevent text relocation and that I used the latest NDK in building the shared library – Nonos Sep 08 '16 at 14:07
  • `-fPIC` can't prevent all text relocation. If your library uses `inline asm`, sometimes the compiler will not be able to make them `PIC`. Therefore, you should fix this by yourself. See the link from Gentoo to see how to do it. – Shmuel H. Sep 08 '16 at 14:24
  • Thank you for the clarification. Please note (as detailed in the question) that if I build the same libraries as shared libraries, they do not contain text relocations so I do not think this is the case here. – Nonos Sep 08 '16 at 17:18
  • @Nonos, You're right. Seems to me like something wrong in the compilation. Anyway, you can pass your soname like that: `gcc -shared -Wl,-soname,your_soname`. If you still want to check the static libraries solution, please upload your makefile. – Shmuel H. Sep 08 '16 at 18:03
  • Please edit the answer to provide your explanation and comments – Nonos Sep 08 '16 at 19:19
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/122931/discussion-between-shmuel-hazan-and-nonos). – Shmuel H. Sep 08 '16 at 19:39
0

I finally figured it out. Since gnutls depends on nettle and gmp while nettle depends on gmp as well I had to build gmp as a shared library and the rest as static. Since libgmp was the only one building without sonames I had no problem to build it this way. So this is my final Android.mk:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libgmp
LOCAL_SRC_FILES := lib/$(TARGET_ARCH_ABI)/libgmp.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libhogweed
LOCAL_SRC_FILES := lib/$(TARGET_ARCH_ABI)/libhogweed.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libnettle
LOCAL_SRC_FILES := lib/$(TARGET_ARCH_ABI)/libnettle.a
LOCAL_SHARED_LIBRARIES := libgmp
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libgnutls
LOCAL_SRC_FILES := lib/$(TARGET_ARCH_ABI)/libgnutls.a
LOCAL_SHARED_LIBRARIES := libgmp
LOCAL_STATIC_LIBRARIES := libhogweed libnettle
include $(PREBUILT_STATIC_LIBRARY)
Nonos
  • 2,327
  • 2
  • 20
  • 33