我正在尝试构建一个概念验证Android应用程序,它使用 OpenSSH 代码与服务器建立SSH会话。
为此,我使用android源码来构建所需的库,然后将它们提升到AndroidStudio本机项目,其中所有内容都应该打包并安装在设备上。
但是,其中一个库(libc ++。so)无法在设备上动态加载消息" java.lang.UnsatisfiedLinkError:dlopen失败:找不到符号" __ register_atfork&# 34;由" libc ++引用。所以" ... "
加载libc ++时会抛出此错误。来自MainActivity java代码的库(我现在一次加载一个库以确定它失败的地方):
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");
}
.............
}
我对错误消息的解释是libc ++所需的符号__register_atfork。所以没有任何其他库定义。但检查库符号表我不明白为什么dlopen无法识别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!!!
检查库的标题和动态部分也没有提供任何关于为什么这可能失败的线索:
$ 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
任何帮助表示赞赏
更新:调查(2)
上__register_atfork@LIBC (2)
的含义
检查readelf sources我们可以看到正在打印(2)
令牌:
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
正在从结构Elf32_External_Sym
加载,成员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个州(第32页):
st_other该成员目前持有0且没有明确的含义。
也许这对 ARM 有一些特殊含义?不,this document没有为st_other
...
更新:调查ELF文件定义中st_other
的含义
发现this post标题为请求扩展符号可见性(st_other)
符号可见性目前由符号的st_other字段的最低2位表示。
该帖子提到了当前进入st_other
...
#define STV_DEFAULT 0
#define STV_INTERNAL 1
#define STV_HIDDEN 2
#define STV_PROTECTED 3
...并提出两个新的可见性属性......
#define STV_SINGLETON 4
#define STV_ELIMINATE 5
readelf符号表输出中的(2)
似乎对应于符号st_other成员上的STV_HIDDEN
属性...