Cross Compiling GSL for Android - android

Cross Compiling GSL for Android
I am attempting to cross compile the GNU Scientific Library (GSL) for Android 4.1 using Autotools. My build and host are as follows:
build="i386-apple-darwin10.8.0"
host="arm-linux-androideabi"
Autotools versions:
GNU Automake version 1.11.3
GNU Autoconf version 2.68
GNU Libtool version 2.4.2
My goal is to compile an executable that I can run from a shell on an emulated device. Thus far, I have compiled GSL and my executable using a toolchain that I generated using the Android Native Development Kit (NDK). I then pushed the shared libraries 'libgsl.so.0' and 'libgslcblas.so.0'(both of which are listed in the dynamic section of my executable) to '/system/lib' and the executable to the device.
Here is the the output of arm-linux-androideabi-readelf -d issm.exe
Dynamic section at offset 0x26a2a4 contains 26 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libgsl.so.0]
0x00000001 (NEEDED) Shared library: [libgslcblas.so.0]
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libc.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
0x0000000f (RPATH) Library rpath: [/Users/gperez/issm/issm-uci/trunk-jpl/externalpackages/gsl/install/lib]
0x00000020 (PREINIT_ARRAY) 0x26d000
0x00000021 (PREINIT_ARRAYSZ) 0x8
0x00000019 (INIT_ARRAY) 0x26d008
0x0000001b (INIT_ARRAYSZ) 1100 (bytes)
0x0000001a (FINI_ARRAY) 0x26d454
0x0000001c (FINI_ARRAYSZ) 8 (bytes)
0x00000004 (HASH) 0x8128
0x00000005 (STRTAB) 0x96a0
0x00000006 (SYMTAB) 0x87f0
0x0000000a (STRSZ) 3588 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000015 (DEBUG) 0x0
0x00000003 (PLTGOT) 0x27239c
0x00000002 (PLTRELSZ) 960 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0xa7ec
0x00000011 (REL) 0xa4a4
0x00000012 (RELSZ) 840 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x00000000 (NULL) 0x0
I realize that the RPATH is incorrect, but if I understand the dynamic linker correctly, then it should fail to find the needed libraries in RPATH and then proceed to check LD_LIBRARY_PATH, where all the libs are situated.
I then proceeded to run my executable, but I was surprised to find the following linking error:
link_image[1936]: 468 could not load needed library 'libgsl.so.0' for './issm.exe' (reloc_library[1285]: 468 cannot locate 'cblas_ctrmv'...
)CANNOT LINK EXECUTABLE
This error lead me to check the contents of 'libgsl.so.0' which are as follows:
Relocation section '.rel.plt' at offset 0x36014 contains 161 entries:
Offset Info Type Sym.Value Sym. Name
00201c54 00002316 R_ARM_JUMP_SLOT 00000000 cblas_ctrmv
00201c58 00002f16 R_ARM_JUMP_SLOT 00000000 cblas_zswap
00201c5c 00003816 R_ARM_JUMP_SLOT 00000000 cblas_zsymm
00201c60 00005016 R_ARM_JUMP_SLOT 00000000 cblas_cgeru
00201c64 00009216 R_ARM_JUMP_SLOT 00000000 cblas_sgemm
00201c68 00009c16 R_ARM_JUMP_SLOT 00000000 cblas_ctrsv
00201c6c 0000c316 R_ARM_JUMP_SLOT 00000000 cblas_sgemv
...
The corresponding '.dynsym' of 'libgslcblas.so.0':
Symbol table '.dynsym' contains 233 entries:
Num: Value Size Type Bind Vis Ndx Name
...
218: 0004e148 64 FUNC GLOBAL DEFAULT 7 __aeabi_f2d
219: 00050314 0 NOTYPE GLOBAL DEFAULT 12 __data_start
220: 0000d69c 1604 FUNC GLOBAL DEFAULT 7 cblas_dgbmv
221: 0002e008 3540 FUNC GLOBAL DEFAULT 7 cblas_ctrmv
222: 00042c34 4184 FUNC GLOBAL DEFAULT 7 cblas_ztbmv
223: 0004de4c 688 FUNC GLOBAL DEFAULT 7 __subdf3
224: 00003dc4 284 FUNC GLOBAL DEFAULT 7 cblas_snrm2
...
Since the very first entry in the Relocation section '.rel.plet' causes the linking to fail, the problem is likely to be with all 'cblas' symbols. I then decided to look at the the Dynamic section of 'libgsl.so.0'
Dynamic section at offset 0x200b60 contains 25 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libc.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
0x0000000e (SONAME) Library soname: [libgsl.so.0]
0x00000010 (SYMBOLIC) 0x0
0x0000000f (RPATH) Library rpath: [:/Users/gperez/issm/issm-uci/trunk-jpl/externalpackages/gsl/install/lib]
0x00000019 (INIT_ARRAY) 0x200c68
0x0000001b (INIT_ARRAYSZ) 8 (bytes)
0x0000001a (FINI_ARRAY) 0x200c70
0x0000001c (FINI_ARRAYSZ) 12 (bytes)
0x00000004 (HASH) 0xb4
0x00000005 (STRTAB) 0x19b1c
0x00000006 (SYMTAB) 0x860c
0x0000000a (STRSZ) 107542 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000003 (PLTGOT) 0x201c48
0x00000002 (PLTRELSZ) 1288 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0x36014
0x00000011 (REL) 0x33f34
0x00000012 (RELSZ) 8416 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x00000016 (TEXTREL) 0x0
0x6ffffffa (RELCOUNT) 1051
0x00000000 (NULL) 0x0
Here, I find it very interesting that the library has relocation symbols that refer to 'cblas' entries, but 'libgslcblas.so.0' is not listed in the dynamic section. This feels wrong to me, but I don't have the expertise to say so definitively. Can anyone help?
I am continuing to investigate, but I would really appreciate any suggestions, corrections or input or any sort!
Questions
Should 'libgslcblas.so.0' be in the Dynamic section of 'libgsl.so.0' given that 'libgsl.so.0' makes references in its relocation section to cblas constructs?
Could the improperly set RPATH be at the root of all this?

I would suggest using the AOSP instead of autotools.
The GSL can be integrated into Android, by wrapping the GSL source code into Android make files.
You can then use the modules defined in this Android make files to access the functionality of the GSL.
However this only provides access to Applications compiled in the AOSP.

Related

Reduce opencv4 dynamic lib .so size

I'm trying to reduce .so file size for an android app, but when I recompile the dynamic library my app crashes with this code
java.lang.UnsatisfiedLinkError: No implementation found for long org.opencv.core.Mat.n_Mat() (tried Java_org_opencv_core_Mat_n_1Mat and Java_org_opencv_core_Mat_n_1Mat__).
I'm also tried to recompile from src, but for some reason, when I add modify the root CMakeLists.txt file (line 153 at this time), the compilation fails because doesn't find a file from samples.
Here is my command to recompile .so from static libraries for arm64
$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ -fpic --sysroot=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/darwin-x86_64/sysroot -target aarch64-linux-android21 -shared -Xlinker -soname=libopencv_java4.so -o libopencv_java4.so -Xlinker --no-as-needed -Xlinker --whole-archive -Xlinker libcpufeatures.a -Xlinker libIlmImf.a -Xlinker liblibjasper.a -Xlinker liblibjpeg-turbo.a -Xlinker liblibpng.a -Xlinker liblibprotobuf.a -Xlinker liblibtiff.a -Xlinker liblibwebp.a -Xlinker libquirc.a -Xlinker libtbb.a -Xlinker libtegra_hal.a -Xlinker libopencv_imgcodecs.a -Xlinker libopencv_imgproc.a -Xlinker libopencv_core.a -Xlinker --no-whole-archive -nostdlib++ -llog -ljnigraphics -landroid -lmediandk -lz
generated .so info
Dynamic section at offset 0x9fabc8 contains 33 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [liblog.so]
0x0000000000000001 (NEEDED) Shared library: [libjnigraphics.so]
0x0000000000000001 (NEEDED) Shared library: [libandroid.so]
0x0000000000000001 (NEEDED) Shared library: [libmediandk.so]
0x0000000000000001 (NEEDED) Shared library: [libz.so]
0x0000000000000001 (NEEDED) Shared library: [libm.so]
0x0000000000000001 (NEEDED) Shared library: [libdl.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so]
0x000000000000000e (SONAME) Library soname: [libopencv_java4.so]
0x0000000000000019 (INIT_ARRAY) 0x9e4948
0x000000000000001b (INIT_ARRAYSZ) 216 (bytes)
0x000000000000001a (FINI_ARRAY) 0x9e4a20
0x000000000000001c (FINI_ARRAYSZ) 16 (bytes)
0x0000000000000004 (HASH) 0x1c8
0x000000006ffffef5 (GNU_HASH) 0x5378
0x0000000000000005 (STRTAB) 0x1d230
0x0000000000000006 (SYMTAB) 0xa8d0
0x000000000000000a (STRSZ) 121597 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000003 (PLTGOT) 0xa0ae18
0x0000000000000002 (PLTRELSZ) 27888 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0xb0260
0x0000000000000007 (RELA) 0x3c658
0x0000000000000008 (RELASZ) 474120 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000000000001e (FLAGS) BIND_NOW
0x000000006ffffffb (FLAGS_1) Flags: NOW
0x000000006ffffffe (VERNEED) 0x3c5f8
0x000000006fffffff (VERNEEDNUM) 3
0x000000006ffffff0 (VERSYM) 0x3ad2e
0x000000006ffffff9 (RELACOUNT) 16950
0x0000000000000000 (NULL) 0x0
original .so info
Dynamic section at offset 0x116d898 contains 32 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libdl.so]
0x0000000000000001 (NEEDED) Shared library: [libm.so]
0x0000000000000001 (NEEDED) Shared library: [liblog.so]
0x0000000000000001 (NEEDED) Shared library: [libjnigraphics.so]
0x0000000000000001 (NEEDED) Shared library: [libz.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so]
0x0000000000000001 (NEEDED) Shared library: [libandroid.so]
0x0000000000000001 (NEEDED) Shared library: [libmediandk.so]
0x000000000000000e (SONAME) Library soname: [libopencv_java4.so]
0x0000000000000019 (INIT_ARRAY) 0x11378f0
0x000000000000001b (INIT_ARRAYSZ) 384 (bytes)
0x000000000000001a (FINI_ARRAY) 0x1137a70
0x000000000000001c (FINI_ARRAYSZ) 16 (bytes)
0x0000000000000004 (HASH) 0x228
0x0000000000000005 (STRTAB) 0x3b328
0x0000000000000006 (SYMTAB) 0xc018
0x000000000000000a (STRSZ) 372415 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000003 (PLTGOT) 0x117dad8
0x0000000000000002 (PLTRELSZ) 49488 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x161668
0x0000000000000007 (RELA) 0x9a138
0x0000000000000008 (RELASZ) 816432 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000000000001e (FLAGS) BIND_NOW
0x000000006ffffffb (FLAGS_1) Flags: NOW
0x000000006ffffffe (VERNEED) 0x9a0d8
0x000000006fffffff (VERNEEDNUM) 3
0x000000006ffffff0 (VERSYM) 0x961e8
0x000000006ffffff9 (RELACOUNT) 26157
0x0000000000000000 (NULL) 0x0
Ok, finally I reduced the size of opencv via build_sdk.py script, just added BUILD_LIST="core,imgproc,imgcodecs,java", to the cmake_vars dictionary in build_library function, also I'm disabled the INSTALL_ANDROID_EXAMPLES to "OFF", and passed the --no_samples_build flag as command line option

Loading C library in Android

I have little to no understanding how low-level programming languages work, so please bear with me.
I need to load compiled C (.so file) library into android 6.0+ (SdkVersion: 23+)
Using:
static {
System.loadLibrary("dsdrv");
}
I get an error:
FATAL EXCEPTION: main
Process: com.logicants.scanner3, PID: 11415
java.lang.UnsatisfiedLinkError: dlopen failed: "/data/app/com.logicants.scanner3-1/lib/arm/libdsdrv.so" has unexpected e_machine: 3
at java.lang.Runtime.loadLibrary(Runtime.java:372)
at java.lang.System.loadLibrary(System.java:1076)
at com.logicants.scanner3.MainActivity.<clinit>(MainActivity.java:13)
at java.lang.Class.newInstance(Native Method)
at android.app.Instrumentation.newActivity(Instrumentation.java:1072)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2478)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1499)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5765)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:683)
I did some digging on the internet and found this: https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-runtime
"On previous versions of Android, if your app requested the system to load a shared library with text relocations, the system displayed a warning but still allowed the library to be loaded. Beginning in this release, the system rejects this library if your app's target SDK version is 23 or higher. To help you detect if a library failed to load, your app should log the dlopen(3) failure, and include the problem description text that the dlerror(3) call returns. To learn more about handling text relocations, see this guide."
So, basically it fails due to: TEXTREL
readelf -a dsdrv.so | grep TEXTREL
Does not return anything
readelf -d dsdrv.so
Returns:
Dynamic section at offset 0x5bd28 contains 24 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libpthread.so.0]
0x00000001 (NEEDED) Shared library: [libstdc++.so.6]
0x00000001 (NEEDED) Shared library: [libm.so.6]
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x0000000c (INIT) 0xd3bc
0x0000000d (FINI) 0x4aec8
0x6ffffef5 (GNU_HASH) 0xd4
0x00000005 (STRTAB) 0x4f30
0x00000006 (SYMTAB) 0x1930
0x0000000a (STRSZ) 24307 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000003 (PLTGOT) 0x5d154
0x00000002 (PLTRELSZ) 2304 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0xcabc
0x00000011 (REL) 0xb5e4
0x00000012 (RELSZ) 5336 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffe (VERNEED) 0xb4e4
0x6fffffff (VERNEEDNUM) 5
0x6ffffff0 (VERSYM) 0xae24
0x6ffffffa (RELCOUNT) 44
0x00000000 (NULL) 0x0
So, I'm assuming it fails due to one of the Shared libraries.
I do not have source code of the library just the compiled *.so file.
How can I resolve this? Is it possible to decompile *.so file and recompile it again, so it would not use TEXTREL.

android error dynamically loading libc++.so native library

I am trying to build a proof-of-concept android application which uses OpenSSH code to establish a SSH session with a server.
For that I am using android sources to build the required libraries and then pull them up to an AndroidStudio native project where everything should be packed and installed on the device.
However, one of the libraries (libc++.so) is failing to load dynamically on the device with the message "java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__register_atfork" referenced by "libc++.so"..."
This error is being thrown when loading libc++.so library from MainActivity java code (I am now loading one library at a time to be sure where it fails):
public class MainActivity extends AppCompatListActivity implements OnHostStatusChangedListener {
...................
static {
System.loadLibrary("dl");
System.loadLibrary("c");
System.loadLibrary("m");
System.loadLibrary("c++"); // <--- Error dlopen failed: cannot locate symbol "__register_atfork" referenced by "libc++.so
System.loadLibrary("ssh");
System.loadLibrary("vrx-native");
}
.............
}
My interpretation of the error message is that symbol __register_atfork required by libc++.so is not defined by any of the other libraries. But examining the libraries symbol tables I dont see why dlopen fails to recognize the symbol being defined on libc.so:
$readelf -s libc++.so
Symbol table '.dynsym' contains 2367 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
.....................
3: 00000000 0 FUNC GLOBAL DEFAULT UND __register_atfork#LIBC (2) <-- Undefined symbol reference
.....................
$readelf -s libc.so
Symbol table '.dynsym' contains 1505 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
.............
62: 00043509 120 FUNC GLOBAL DEFAULT 13 __register_atfork##LIBC
..............
7518: 00043509 120 FUNC GLOBAL DEFAULT 13 __register_atfork <-- symbol defined and exported by libc.so!!!
Examining the header and dynamic section of the libraries also does not provide any clue as to why this might be failing:
$ readelf -hd 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: ARM
Version: 0x1
Entry point address: 0x0
Start of program headers: 52 (bytes into file)
Start of section headers: 573972 (bytes into file)
Flags: 0x5000200, Version5 EABI, soft-float ABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 9
Size of section headers: 40 (bytes)
Number of section headers: 29
Section header string table index: 28
Dynamic section at offset 0x8abf8 contains 29 entries:
Tag Type Name/Value
0x00000003 (PLTGOT) 0x8dfe8
0x00000002 (PLTRELSZ) 8216 (bytes)
0x00000017 (JMPREL) 0x2d738
0x00000014 (PLTREL) REL
0x6000000f (Operating System specific: 6000000f) 0x2b280
0x60000010 (Operating System specific: 60000010) 0x24b8
0x00000013 (RELENT) 8 (bytes)
0x6ffffffa (RELCOUNT) 397
0x00000006 (SYMTAB) 0x21a0
0x0000000b (SYMENT) 16 (bytes)
0x00000005 (STRTAB) 0xb590
0x0000000a (STRSZ) 107756 (bytes)
0x00000004 (HASH) 0x25a7c
0x00000001 (NEEDED) Shared library: [libdl.so]
0x00000001 (NEEDED) Shared library: [libc.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x0000000e (SONAME) Library soname: [libc++.so]
0x0000001a (FINI_ARRAY) 0x8b3c0
0x0000001c (FINI_ARRAYSZ) 4 (bytes)
0x00000019 (INIT_ARRAY) 0x8dbf4
0x0000001b (INIT_ARRAYSZ) 4 (bytes)
0x0000001e (FLAGS) BIND_NOW
0x6ffffffb (FLAGS_1) Flags: NOW
0x6ffffff0 (VERSYM) 0x29f94
0x6ffffffc (VERDEF) 0x2b214
0x6ffffffd (VERDEFNUM) 1
0x6ffffffe (VERNEED) 0x2b230
0x6fffffff (VERNEEDNUM) 2
0x00000000 (NULL) 0x0
$ readelf -hd 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: ARM
Version: 0x1
Entry point address: 0x0
Start of program headers: 52 (bytes into file)
Start of section headers: 757116 (bytes into file)
Flags: 0x5000200, Version5 EABI, soft-float ABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 10
Size of section headers: 40 (bytes)
Number of section headers: 33
Section header string table index: 30
Dynamic section at offset 0x8232c contains 27 entries:
Tag Type Name/Value
0x00000003 (PLTGOT) 0x835bc
0x00000002 (PLTRELSZ) 5232 (bytes)
0x00000017 (JMPREL) 0x105c4
0x00000014 (PLTREL) REL
0x00000011 (REL) 0xd85c
0x00000012 (RELSZ) 11624 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffa (RELCOUNT) 1304
0x00000006 (SYMTAB) 0x1c0
0x0000000b (SYMENT) 16 (bytes)
0x00000005 (STRTAB) 0x5fd0
0x0000000a (STRSZ) 17483 (bytes)
0x00000004 (HASH) 0xa41c
0x00000001 (NEEDED) Shared library: [libdl.so]
0x0000000e (SONAME) Library soname: [libc.so]
0x00000019 (INIT_ARRAY) 0x83304
0x0000001b (INIT_ARRAYSZ) 36 (bytes)
0x0000001a (FINI_ARRAY) 0x83328
0x0000001c (FINI_ARRAYSZ) 4 (bytes)
0x0000001e (FLAGS) BIND_NOW
0x6ffffffb (FLAGS_1) Flags: NOW
0x6ffffff0 (VERSYM) 0xcbc4
0x6ffffffc (VERDEF) 0xd788
0x6ffffffd (VERDEFNUM) 5
0x6ffffffe (VERNEED) 0xd82c
0x6fffffff (VERNEEDNUM) 1
0x00000000 (NULL) 0x0
Any help appreciated
Update: Investigating the meaning of (2) on __register_atfork#LIBC (2)
Checking readelf sources we can see the (2) token is being printed from:
if (version_string)
{
if (sym_info == symbol_undefined)
printf ("#%s (%d)", version_string, vna_other);
else
printf (sym_info == symbol_hidden ? "#%s" : "##%s",
version_string);
}
vna_other is being loaded from struct Elf32_External_Sym, member st_other...
typedef struct {
unsigned char st_name[4]; /* Symbol name, index in string tbl */
unsigned char st_value[4]; /* Value of the symbol */
unsigned char st_size[4]; /* Associated symbol size */
unsigned char st_info[1]; /* Type and binding attributes */
unsigned char st_other[1]; /* No defined meaning, 0 */
unsigned char st_shndx[2]; /* Associated section index */
} Elf32_External_Sym;
ELF specification states (on page 32):
st_other This member currently holds 0 and has no defined meaning.
Maybe this has some special meaning on ARM? No, this document does not define anything arm-specific for st_other...
Update: Investigating the meaning of st_other in the ELF file definition
Found this post titled Request to extend symbol visibilities (st_other)
Symbol visibility is currently represented by the least significant 2 bits of a symbol's st_other field.
The post mentions the visibility attributes that currently goes into st_other...
#define STV_DEFAULT 0
#define STV_INTERNAL 1
#define STV_HIDDEN 2
#define STV_PROTECTED 3
...and proposes two new visibility attributes...
#define STV_SINGLETON 4
#define STV_ELIMINATE 5
It seems (2) on readelf symbol table output corresponds to STV_HIDDEN attribute on the symbol st_other member...

Android NDK links shared libraries libxxx.so.ver instead of libxxx.so

I've compiled my own shared library which depends on external shared libraries (ffmpeg and x264) using ndk-build. I've defined external libraries as it is described in documentation:
LOCAL_PATH := $(my-root-dir)/external_libs
include $(CLEAR_VARS)
LOCAL_MODULE := avcodec
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/lib/libavcodec.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/$(TARGET_ARCH_ABI)/include
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avutil
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/lib/libavutil.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/$(TARGET_ARCH_ABI)/include
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := swscale
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/lib/libswscale.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/$(TARGET_ARCH_ABI)/include
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := x264
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/lib/libx264.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/$(TARGET_ARCH_ABI)/include
include $(PREBUILT_SHARED_LIBRARY)
and have installed external shared libraries for all needed ABIs:
external_libs
- armeabi
- - include
- - lib
- - - libavcodec.so -> libavcodec.so.57.24.101
- - - libavcodec.so.57 -> libavcodec.so.57.24.101
- - - libavcodec.so.57.24.101
- - - libavutil.so -> libavutil.so.55.16.101
- - - libavutil.so.55 -> libavutil.so.55.16.101
- - - libavutil.so.55.16.101
- - - libswresample.so -> libswresample.so.2.0.101
- - - libswresample.so.2 -> libswresample.so.2.0.101
- - - libswresample.so.2.0.101
- - - libswscale.so -> libswscale.so.4.0.100
- - - libswscale.so.4 -> libswscale.so.4.0.100
- - - libswscale.so.4.0.100
- - - libx264.so -> libx264.so.148
- - - libx264.so.148
- armeabi-v7a
- - include
- - lib
- - - libavcodec.so -> libavcodec.so.57.24.101
- - - libavcodec.so.57 -> libavcodec.so.57.24.101
- - - libavcodec.so.57.24.101
- - - libavutil.so -> libavutil.so.55.16.101
- - - libavutil.so.55 -> libavutil.so.55.16.101
- - - libavutil.so.55.16.101
... (etc)
In my library's Android.mk I've added reference to this external libraries:
LOCAL_SHARED_LIBRARIES += libx264
Project has builded just fine, external libraries have been copied to the lib/$(TARGET_ARCH_ABI):
lib
- armeabi
- - libavcodec.so
- - libavutil.so
- - libswscale.so
- - libx264.so
- armeabi-v7a
- - libavcodec.so
- - libavutil.so
- - libswscale.so
- - libx264.so
and than to device/simulator. But when I load my library in application with System.loadLibrary("mylibrary"); I get error:
java.lang.UnsatisfiedLinkError: dlopen failed: library "libx264.so.148" not found
at java.lang.Runtime.loadLibrary(Runtime.java:372)
When I inspect my library with
arm-linux-androideabi-readelf -d libs/armeabi-v7a/libmylibrary.so
I get this:
Dynamic section at offset 0x12d34c contains 42 entries:
Tag Type Name/Value
0x00000003 (PLTGOT) 0x12eb00
0x00000002 (PLTRELSZ) 2536 (bytes)
0x00000017 (JMPREL) 0x3a264
0x00000014 (PLTREL) REL
0x00000011 (REL) 0x352ac
0x00000012 (RELSZ) 20408 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffa (RELCOUNT) 2546
0x00000006 (SYMTAB) 0x148
0x0000000b (SYMENT) 16 (bytes)
0x00000005 (STRTAB) 0x10c58
0x0000000a (STRSZ) 106907 (bytes)
0x00000004 (HASH) 0x2adf4
0x00000001 (NEEDED) Shared library: [libx264.so.148]
0x00000001 (NEEDED) Shared library: [libavcodec.so.57]
0x00000001 (NEEDED) Shared library: [libswscale.so.4]
0x00000001 (NEEDED) Shared library: [libavutil.so.55]
0x00000001 (NEEDED) Shared library: [liblog.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
0x00000001 (NEEDED) Shared library: [libstdc++.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libc.so]
0x0000000e (SONAME) Library soname: [libmylibrary.so]
0x0000001a (FINI_ARRAY) 0x12d77c
0x0000001c (FINI_ARRAYSZ) 8 (bytes)
0x00000019 (INIT_ARRAY) 0x12e344
0x0000001b (INIT_ARRAYSZ) 8 (bytes)
0x00000016 (TEXTREL) 0x0
0x00000010 (SYMBOLIC) 0x0
0x0000001e (FLAGS) SYMBOLIC TEXTREL BIND_NOW
0x6ffffffb (FLAGS_1) Flags: NOW
0x6ffffff0 (VERSYM) 0x330cc
0x6ffffffc (VERDEF) 0x35230
0x6ffffffd (VERDEFNUM) 1
0x6ffffffe (VERNEED) 0x3524c
0x6fffffff (VERNEEDNUM) 3
0x00000000 (NULL) 0x0
Why are there references in my libmylibrary.so to libx264.so.148, libavcodec.so.57, etc and not to libx264.so, libavcodec.so, etc as expected?
The linker looks at the soname of libraries, not the file names. You can ask ./configure to generate sonames without version suffix

Cross-compiling for Android

I'm trying to cross-compile dropbear for android. The files appear to compile find, but when executed give "program : not found." I did a find and the libraries marked NEEDED appear to be located in the cross-compile environment. I have compiled other programs with this toolchain.
arm-none-linux-gnueabi-readelf -d dropbear
Dynamic section at offset 0x1c158 contains 27 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libutil.so.1]
0x00000001 (NEEDED) Shared library: [libcrypt.so.1]
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x0000000c (INIT) 0x9428
0x0000000d (FINI) 0x1e1b4
0x00000019 (INIT_ARRAY) 0x2c14c
0x0000001b (INIT_ARRAYSZ) 4 (bytes)
0x0000001a (FINI_ARRAY) 0x2c150
0x0000001c (FINI_ARRAYSZ) 4 (bytes)
0x00000004 (HASH) 0x8168
0x00000005 (STRTAB) 0x8ba0
0x00000006 (SYMTAB) 0x84b0
0x0000000a (STRSZ) 970 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000015 (DEBUG) 0x0
0x00000003 (PLTGOT) 0x2c258
0x00000002 (PLTRELSZ) 848 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0x90d8
0x00000011 (REL) 0x90c8
0x00000012 (RELSZ) 16 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffe (VERNEED) 0x9048
0x6fffffff (VERNEEDNUM) 4
0x6ffffff0 (VERSYM) 0x8f6a
0x00000000 (NULL) 0x0
Did you apply the "patch" to dropbear, because dropbear uses /etc/passwd and that does not exist on android.
Found this on Installing Dropbear - MyWiki
Dropbear needs to be patched to work with Android. Android does not use a ‘/etc/passwd’ file, so that needs to be patched together with some directory changes. This also adds a statically password. This password is located at the bottom of ‘debug.h’ in the dropbear directory. The default password is “password”. The patch can be found here: http://pastebin.com/f3dedc5e7
I know dropbear can compile and run on android because CyanogenMOD, along with most of the other ROMs I have used have it on the system.
I found the problem. I was compiling w/o the STATIC=1 flag. Thanks for the reply! Thanks for the reply! I got the patched source from cyanogen's github

Categories

Resources