Openssl for Android x86_64 and mips64 - android

I have built openssl for 5/7 of the android-21 (android-L) architectures: armeabi, armeabi-v7a, arm64, mips, x86. However I am unable to build it for x86_64 and mips64.
What I'm doing...
x86 - working
The following is my working script for x86, using a toolchain created by make-standalone-toolchain:
export ANDROID_NDK_ROOT=/Users/jacsteve/dev/android/ndk
export ANDROID_API=android-21
export ANDROID_ARCH=arch-x86
export ANDROID_EABI=i686-linux-android-4.9
export ANDROID_SYSROOT=$ANDROID_NDK_ROOT/platforms/$ANDROID_API/arch-x86
export ANDROID_TOOLCHAIN=/tmp/toolchain/x86
export ANDROID_DEV=$ANDROID_SYSROOT/usr
export SYSTEM=android
export ARCH=x86
export CROSS_COMPILE=i686-linux-android-
export CFLAGS="--sysroot=$ANDROID_SYSROOT"
export CPPFLAGS="--sysroot=$ANDROID_SYSROOT"
export CXXFLAGS="--sysroot=$ANDROID_SYSROOT"
./Configure android-x86 shared no-asm -no-ssl2 -no-ssl3 -no-comp -no-hw --cross-compile-prefix=$CROSS_COMPILE --openssldir=/tmp/ssl/x86
make depend
make
make install
This works fine, and leaves me with libssl.so and libcrypto.so in /tmp/ssl/x86
x86_64 - fails
However, x86_64 fails. Here's the script:
export ANDROID_NDK_ROOT=/Users/jacsteve/dev/android/ndk
export ANDROID_API=android-21
export ANDROID_ARCH=arch-x86_64
export ANDROID_EABI=x86_64-linux-android-4.9
export ANDROID_SYSROOT=$ANDROID_NDK_ROOT/platforms/$ANDROID_API/arch-x86_64
export ANDROID_TOOLCHAIN=/tmp/toolchain/x86_64
export ANDROID_DEV=$ANDROID_SYSROOT/usr
export SYSTEM=android
export ARCH=x86_64
export CROSS_COMPILE=x86_64-linux-android-
export CFLAGS="--sysroot=$ANDROID_SYSROOT"
export CPPFLAGS="--sysroot=$ANDROID_SYSROOT"
export CXXFLAGS="--sysroot=$ANDROID_SYSROOT"
./Configure android-x86 shared no-asm -m64 -no-ssl2 -no-ssl3 -no-comp -no-hw --cross-compile-prefix=$CROSS_COMPILE --openssldir=/tmp/ssl/x86_64
make depend
make
make install
The Errors...
x86_64
I get a load of error messages from the make call that look like this:
/private/tmp/toolchain/x86_64/bin/../lib/gcc/x86_64-linux-android/4.9/../../../../x86_64-linux-android/bin/ld:
error: libcrypto.a(cryptlib.o): incompatible target
/private/tmp/toolchain/x86_64/bin/../lib/gcc/x86_64-linux-android/4.9/../../../../x86_64-linux-android/bin/ld:
error: libcrypto.a(mem.o): incompatible target
...
collect2: error: ld returned 1 exit status
It looks to me like x86_64-linux-android-gcc is compiling everything fine, but when we get to the linking stage, x86_64-linux-android-ld can't read the compiled object files.
mips64
Using a similar setup for mips64 (with ./Configure android-mips ...) I get the following error, which looks to be a similar issue to do with mips64-linux-android-ld being unable to read object files:
/Users/jacsteve/dev/android/ndk/platforms/android-21/arch-mips64/usr/lib/libdl.so: error adding symbols: File in wrong format
collect2: error: ld returned 1 exit status
Does anyone know how to build the x86_64 and mips64 architectures successfully?

Solved!
Instead of
./Configure android-x86 ...
I used
./Configure linux-generic64 ...
I also used linux-generic32 for the 32bit architectures.

Running make clean before ./Configure solved the problem for me.

The error from building openssl for mips64, I guess, resulted from the incompatible ABI format between objects and libraries, which the format objects is mips-ELF64, while libraries provided by ANDROID_NDK is mips ELF32
cd ${ANDROID_NDK_HOME}/platforms/android-24/arch-mips64/usr/lib
readelf -h libc.so
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: MIPS R3000
Version: 0x1
Entry point address: 0xa7d0
Start of program headers: 52 (bytes into file)
Start of section headers: 204792 (bytes into file)
Flags: 0x50001007, noreorder, pic, cpic, o32, mips32
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 6
Size of section headers: 40 (bytes)
Number of section headers: 18
Section header string table index: 15

Related

Libgmp NDK Build issue with x86_64

I am trying to build libgmp with NDK as static (shared also doesn't work), I need this to link with nettle and gnutls. The versions I am using below:
GMP: 6.1.2
NDK: r16b
Target: x86_64
API: android-27
Env: Ubuntu 16.04 (Windows shell)
So I download a tar of libgmp from their website and then the android standalong toolchain:
$NDK/build/tools/make_standalone_toolchain.py --arch "x86_64" --api 27 \
--stl=libc++ --install-dir /tmp/android-toolchain --force
Set the environment to link with NDK
# Prefix is out the output folder location
PREBUILT=/tmp/android-toolchain
CROSS_COMPILE=$PREBUILT/bin/x86_64-
CFLAGS="-isystem /tmp/android-toolchain/sysroot/usr/include/x86_64/ -D__ANDROID_API__=27-I$PREFIX/include"
export LDFLAGS="-Wl,-rpath-link=/tmp/android-toolchain/sysroot/usr/lib -L$/tmp/android-toolchain/sysroot/usr/lib -lc -lm -ldl -llog -nostdlib -lgcc -L$PREFIX/lib"
export CPPFLAGS="$CFLAGS"
export CFLAGS="$CFLAGS"
export CXXFLAGS="$CFLAGS"
export CXX="clang++"
export AS="clang"
export CC="clang"
export NM="${CROSS_COMPILE}nm"
export STRIP="${CROSS_COMPILE}strip"
export RANLIB="${CROSS_COMPILE}ranlib"
export AR="${CROSS_COMPILE}ar"
export LD="${CROSS_COMPILE}ld"
then ran configure
./configure
--prefix=$PREFIX \
--host="x86_64-linux" \
--build=x86_64-unknown-linux-gnu \
--disable-dependency-tracking \
--enable-static \
--disable-shared \
|| exit 1
make -j4 || exit 1
Prefix points to output directory, (also tried host x86_64-linux-android). It configures but then after that when running make, it will try to compile a bunch of binaries that auto create a bunch of files such as gen-fib.c -> gen-fib binary.
Makefile then runs that binary to create the header file (fib_table.h) and the source fib_table.c. When Makefile runs (I believe something like)
gen-fib header <number> <number> > fib_table.h
It outputs nothing, so fib_table.h is empty (0 bytes). I tried to run it from command line and nothing appears. Tried to create a file in gen-fib.c and have it compiled to create a dummy file and nothing happens. The binary executes nothing, does not run at all!
Now I have compiled this successfully with arm64 (aarch64 or arm64-v8a) and x86 (and of course ran make distclean between different hosts). I tried to compare the config.log with x86 and x86_64 which the only difference being the host argument in the configure and x86 android toolchain. For my x86_64 log file you can read that here:
https://pastebin.com/LLEbDz11
If anyone knows why the binaries (like gen-fibs) do not run after compiling them for x86_64 (but other abi like x86 and arm64) please let me know.
Thanks in advance!!
I figured out that the binaries were not building because it was using the toolchain's clang. Using
export CC_FOR_BUILD=/usr/bin/gcc
Uses the gcc from linux to compile it correctly.

Cross Compile with autoconf with Android toolchain

Objective Cross compile Cisco libsrtp for Android using NDK toolchain and use libsrtp.a to statically link against my own library.
Setup : I make use of the following file
<setup.sh>
export CROSS_SYSROOT=/home/psurana/aa/sysroot
export CROSS_COMPILE=aarch64-linux-android-
export SYSROOT=/home/psurana/aa/sysroot
export CC="${CROSS_COMPILE}gcc --sysroot=${SYSROOT}"
export CXX="${CROSS_COMPILE}gxx --sysroot=${SYSROOT}"
PATH=/home/psurana/aa/bin:$PATH
then I do the following configure:
source setup.sh && ./configure --host=aarch64-linux-android --build=`./config.guess` && make -j
This compiles it for me. doing a readelf -h libsrtp.a, yields--
File: libsrtp.a(ut_sim.o)
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: AArch64
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 1480 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 64 (bytes)
Number of section headers: 10
Section header string table index: 7
So far so good.
Problem
However, when I link libsrtp.a as a prebuilt static library, I get following errors:
./srtp/libsrtp.a(rand_source.o): In function `rand_source_init':
err.c:(.text+0x0): undefined reference to `stdout'
err.c:(.text+0xc): undefined reference to `stdout'
and,
rand_source.c:(.text+0x28): undefined reference to `stderr'
rand_source.c:(.text+0x3c): undefined reference to `stderr'
My understanding is that Android does not have stderr in its libc, but then how does libsrtp get these?
I have previously built the same library using something similar and I know it builds. I do not know what the error might be.
I usually get this undefined reference with libc in any platform after 21 so I usually add -D__ANDROID_API__=21 to CFLAGS and it ends up fixing it. I believe the issue comes from the new unified headers in newer ndk versions.

Native libs cross compiled from ubuntu linux targeting arm (android)

I'm experimenting with native libs cross compiled from ubuntu. What I really want is to be able to compile my c++ libraries and use them in a Xamarin.Android app.
First, I have the arm gcc compiler: arm-linux-gnueabi-gcc. I have a simple lib (libmr.so) that has one function void Print(); that prints something to the console. I'm compiling with:
arm-linux-gnueabi-gcc -Wall -shared -o libmr.so mr.c
When inspecting it using file libmr.so everything seems to be good. However when I'm including it with my android app and try to load it, it is as if it doesn't exist. I'm certain it is there, the path is absolutely correct as I tried to load another lib (libmonodroid.so) from the same folder and it worked.
I tried inspecting both libs to find some kind of a difference:
$ objdump -x libmr.so | grep NEEDED
NEEDED libc.so.6
$ objdump -x libmonodroid.so | grep NEEDED
NEEDED libc.so
... (in addition to other libs)
This is the only difference I'm finding between the two. libmonodroid.so loads properly but libmr.so acts as if it doesn't exist. (I'm using dlopen to load a lib)
EDIT:
I built an executable using the same toolchain, gave me a clue:
Static linking with libc: arm-linux-gnueabi-gcc -Wall -o hi source.c -static. Pushed hi to my android devices and executed it with adb. Result: SUCCESS!
Dynamic linking with libc: arm-linux-gnueabi-gcc -Wall -o hi source.c. Result: it's not even there! Meaning ./hi gives /system/bin/sh: ./hi: not found although it's absolutely there.
So, looks like libc is really the culprit? Maybe I need to link dynamically with not libc.so.6 but with libc.so just like libmonodroid.so is doing?
Check this out for anyone having the same problem. Download the ndk, there's a standalone toolchain for building native libs that run on android that you can extract (you won't need the whole ndk).
I was able to run a basic app on ubuntu 15.04 with this Makefile in the same dir as my hi.c:
$ cat hi.c # create hi.c with favorite editor
#include <stdio.h>
int main(int argc, char** argv) {
int uid = getuid();
int eid = geteuid();
printf("Hello world\n");
printf("You are uid: %d and eid; %d", uid, eid);
return 0;
}
$ cat Makefile # create two line Makefile
CC=arm-linux-gnueabi-gcc
LDFLAGS=-static
$ make hi # build arm based hi executable file
arm-linux-gnueabi-gcc -static hi.c -o hi
$ file hi # check file type
hi: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=17b65e60cdd32449ac237bfd1b8238bfa1d416a0, not stripped
$ adb push hi /data/local/tmp # copy to droid fon
4403 KB/s (593252 bytes in 0.131s)
$ adb shell /data/local/tmp/hi # run hi executable
adb shell /data/local/tmp/hi
Hello world
You are uid: 2000 and eid; 2000
$ uname -a
Linux lenny 3.19.0-28-generic #30-Ubuntu SMP Mon Aug 31 15:52:51 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
Note that I do not have any NDK installed.

How to disable Binary Translator on the Android Emulator X86?

I am still getting warning requires library libhoudini by logcat, also i have compiled all library into arch x86.
On the Emulator without support Binary Translator - Log:
04-14 18:05:05.304: D/FFMpeg(992): ### Try to load lib: jniaudio
04-14 18:05:05.304: D/dalvikvm(992): Trying to load lib /data/data/com.app.test/lib/libjniaudio.so 0xa6a0d230
04-14 18:05:05.304: D/FFMpeg(992): Couldn't load lib: jniaudio - Cannot load library: load_library[1093]: Library '/system/lib/libhoudini.so' not found
On the Emulator with installed support Binary Translator - Log:
04-14 18:05:05.304: D/FFMpeg(992): ### Try to load lib: jniaudio
04-14 19:34:00.764: D/dalvikvm(1171): Trying to load lib /data/data/com.app.test/lib/libjniaudio.so 0xa68cbd98
04-14 19:34:00.804: E/dalvikvm(1171): The lib may be ARM... trying to load it [/data/data/com.app.test/lib/libjniaudio.so] using houdini
04-14 19:34:00.808: D/houdini(1171): [1171] Loading library(version: 2.0.5.42475 RELEASE)... successfully.
04-14 19:34:00.808: E/dalvikvm(1171): dvm_dlopen: unable to open /data/data/com.app.test/lib/libjniaudio.so
Application.mk
APP_ABI := x86
APP_PLATFORM := android-14
I can't load native libraries on my emulator, but system makes wrong for determining the target architecture of shared library. I'd be grateful if someone could explain.?
UPDATE 1.
/obj/local/x86/libjniaudio.so - here header information of shared library.
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x0
Start of program headers: 52 (bytes into file)
Start of section headers: 68664 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 7
Size of section headers: 40 (bytes)
Number of section headers: 32
Section header string table index: 31
are you 100% sure your library is an x86 binary ?
The binary translator shouldn't load up in this case.
You can check the real ABI of your files using readelf, file, or this Android app I've made: https://play.google.com/store/apps/details?id=com.xh.nativelibsmonitor.app (x86 only for now)

error when trying to compile wrapper for openssl library libcrypto.a

I'm trying to build a dynamic library for android wrapper around libcrypto.a as described in
http://wiki.openssl.org/index.php/FIPS_Library_and_Android#Using_FIPS_OpenSSL_in_a_real_Application
I've produced the libcrypto.a as suggested on the page, but when I try to compile my wrapper.c I get a linker error, multiple definition of 'atexit'
Here's the command line I'm using to compile:
arm-linux-androideabi-gcc wrapper.c -fPIC -shared -I/usr/local/ssl/android-14/include -Wl,-Bstatic -lcrypto -L/usr/local/ssl/android-14/lib -o libwrapper.so --sysroot=/Users/scoleman/android-ndk-r9d/platforms/android-14/arch-arm -Wl, -Bdynamic
Here are the results:
/Users/scoleman/android-ndk-r9d/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: error: /Users/scoleman/android-ndk-r9d/platforms/android-14/arch-arm/usr/lib/libc.a(atexit.o): multiple definition of 'atexit'
/Users/scoleman/android-ndk-r9d/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: /Users/scoleman/android-ndk-r9d/platforms/android-14/arch-arm/usr/lib/crtbegin_so.o: previous definition here
/Users/scoleman/android-ndk-r9d/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: error: cannot find -ldl
collect2: ld returned 1 exit status
Here's my wrapper.c:
#include <string.h>
#include <jni.h>
int MY_FIPS_mode() {
int mode = mode = FIPS_mode();
return mode;
}
Here's the command line I'm using to compile:
arm-linux-androideabi-gcc wrapper.c -fPIC -shared -I/usr/local/ssl/android-14/include -Wl,-Bstatic -lcrypto -L/usr/local/ssl/android-14/lib -o libwrapper.so --sysroot=/Users/scoleman/android-ndk-r9d/platforms/android-14/arch-arm -Wl, -Bdynamic
I was able to duplicate the issue with your command line. The way I would approach this is (line breaks added for readability):
arm-linux-androideabi-gcc wrapper.c -fPIC -shared -o libwrapper.so
--sysroot=.../android-ndk-r9d/platforms/android-14/arch-arm
-I/usr/local/ssl/android-14/include
/usr/local/ssl/android-14/lib/libssl.a
/usr/local/ssl/android-14/lib/libcrypto.a
-ldl
--sysroot will bring in the platform headers and libraries for Android 4.0 (API 14). That should be where atexit is defined. I think the -Bstatic and -Bdynamic might be complicating things since atexit was provided by both libc.a and crtbegin_so.o.
I avoid -Bstatic and -Bdynamic. When I want static linking, I specifically call out the full pathname of the static library, like /usr/local/ssl/android-14/lib/libcrypto.a. Remember, an archive is a collection of object files (*.o), so you can use it wherever you can use an object file.
Using the setenv-android.sh script from the page and your source, I was not able to duplicate:
$ . ./setenv-android.sh
ANDROID_NDK_ROOT: /opt/android-ndk-r9
ANDROID_EABI: arm-linux-androideabi-4.6
ANDROID_API: android-14
ANDROID_SYSROOT: /opt/android-ndk-r9/platforms/android-14/arch-arm
ANDROID_TOOLCHAIN: /opt/android-ndk-r9/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin
CROSS_COMPILE: arm-linux-androideabi-
ANDROID_DEV: /opt/android-ndk-r9/platforms/android-14/arch-arm/usr
$ cat wrapper.c
#include <string.h>
#include <jni.h>
#include <openssl/evp.h>
int MY_FIPS_mode() {
int mode = FIPS_mode();
return mode;
}
$ arm-linux-androideabi-gcc wrapper.c -fPIC -shared -o libwrapper.so \
> --sysroot=$ANDROID_SYSROOT \
> -I/usr/local/ssl/android-14/include \
> /usr/local/ssl/android-14/lib/libssl.a \
> /usr/local/ssl/android-14/lib/libcrypto.a \
> -ldl
$ ls
libwrapper.so setenv-android.sh wrapper.c
$ arm-linux-androideabi-readelf -h libwrapper.so
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: ARM
Version: 0x1
Entry point address: 0x0
Start of program headers: 52 (bytes into file)
Start of section headers: 244660 (bytes into file)
Flags: 0x5000000, Version5 EABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 7
Size of section headers: 40 (bytes)
Number of section headers: 34
Section header string table index: 33
$ arm-linux-androideabi-nm -D libwrapper.so | grep MY_FIPS_mode
00009fa4 T MY_FIPS_mode

Categories

Resources