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...
User contributions licensed under CC BY-SA 3.0