gpt4 book ai didi

Android动态链接库无法解析主程序符号

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:58:58 28 4
gpt4 key购买 nike

我可以用 C 语言成功创建一个链接到库的程序,并且能够调用该库的函数。如果该库从主程序调用函数,则会出现错误:

root@android:/data/local/tmp # ./helloworld                                    
link_image[1966]: 637 could not load needed library 'libhello.so' for './helloworld' (reloc_library[1315]: 637 cannot locate 'crossfunction'...) CANNOT LINK EXECUTABLE

代码在两个 C 文件中,我还包含了 Makefile。 hello.c 是包含函数 hello 的库,该函数由 main.c(主程序)调用。函数 hello 尝试调用函数 crossfunction 并且在 android 中不起作用(在 Linux 中它工作得很好)。我怀疑来自 android 链接器,但目前还没有证据(请参阅 https://android.googlesource.com/platform/bionic/+/froyo-release/linker/README.TXT )。

另一个好的提示可能是 libhello.so 文件中交叉函数的 readelf 输出中的 NOTYPE 赋值。请看下面。

         5: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND crossfunction

可能在编译器标志或链接器标志中有任何提示吗?

::::::::::::::
main.c
::::::::::::::
#include <stdio.h>
extern void hello(const char* name);
int main(void) {
hello("World!");
}

void crossfunction(void) {
printf("This is called from the library\n");
}
::::::::::::::
hello.c
::::::::::::::
#include <stdio.h>
extern void crossfunction(void);
static char *s;
void hello(const char* name) {
s = "my second name";
printf("Hello %s %s!\n", s, name);
crossfunction();
}

为了编译,我使用 agcc 包装器和 android ndk https://github.com/nitomartinez/agcc

这是生成文件:

OBJECTS=main.o
LIB=libhello.so
LIBOBJ=hello.o
TARGET=helloworld
TARGETDIR=/data/local/tmp
CC=agcc

.PHONY: all install run clean distclean

all: $(TARGET) $(LIB)

hello.o: hello.c Makefile
$(CC) $(CFLAGS) -c -o hello.o hello.c

$(TARGET): $(OBJECTS) $(LIB) Makefile
$(CC) -Wl,-rpath=$(TARGETDIR) -lhello -L . -o $(TARGET) $(OBJECTS)

$(LIB): $(LIBOBJ) Makefile
$(CC) -shared -o $(LIB) $(LIBOBJ)

install: $(TARGET)
adb push $(TARGET) $(TARGETDIR)/$(TARGET)
adb push $(LIB) $(TARGETDIR)/$(LIB)

run: install
adb shell "export LD_LIBRARY_PATH=$(TARGETDIR); $(TARGETDIR)/$(TARGET) "

我查看了 readelf 位,但我发现 .dynsym、.rel.plt 和 .symtab 部分没有实质性差异。

hell 世界

Relocation section '.rel.plt' at offset 0x33c contains 3 entries:
Offset Info Type Sym.Value Sym. Name
0000954c 00000416 R_ARM_JUMP_SLOT 00008368 hello
00009550 00000516 R_ARM_JUMP_SLOT 00008374 puts
00009554 00000816 R_ARM_JUMP_SLOT 00008380 __libc_init

Symbol table '.dynsym' contains 16 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 000083b0 32 FUNC GLOBAL DEFAULT 7 crossfunction
2: 00008450 0 NOTYPE GLOBAL DEFAULT ABS __exidx_end
3: 00009558 0 NOTYPE GLOBAL DEFAULT ABS _bss_end__
4: 00008368 0 FUNC GLOBAL DEFAULT UND hello
5: 00008374 0 FUNC GLOBAL DEFAULT UND puts
...
Symbol table '.symtab' contains 62 entries:
Num: Value Size Type Bind Vis Ndx Name
...
41: 000083b0 32 FUNC GLOBAL DEFAULT 7 crossfunction
42: 00008450 0 NOTYPE GLOBAL DEFAULT ABS __exidx_end
43: 00009558 0 NOTYPE GLOBAL DEFAULT ABS _bss_end__
44: 00008368 0 FUNC GLOBAL DEFAULT UND hello
45: 00008374 0 FUNC GLOBAL DEFAULT UND puts
...
55: 00008390 32 FUNC GLOBAL DEFAULT 7 main
...

对于 libhello.so

Relocation section '.rel.plt' at offset 0xae8 contains 7 entries:
Offset Info Type Sym.Value Sym. Name
000032cc 00000516 R_ARM_JUMP_SLOT 00000000 crossfunction
000032d0 00000616 R_ARM_JUMP_SLOT 00000000 printf
000032d4 00000f16 R_ARM_JUMP_SLOT 00000000 __cxa_begin_cleanup
000032d8 00001516 R_ARM_JUMP_SLOT 00000000 memcpy
000032dc 00001f16 R_ARM_JUMP_SLOT 00000000 abort
...

Symbol table '.dynsym' contains 64 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
...
5: 00000000 0 NOTYPE GLOBAL DEFAULT UND crossfunction
6: 00000000 0 FUNC GLOBAL DEFAULT UND printf
...
19: 00000b88 100 FUNC GLOBAL DEFAULT 7 hello
21: 00000000 0 FUNC GLOBAL DEFAULT UND memcpy
...

Symbol table '.symtab' contains 138 entries:
Num: Value Size Type Bind Vis Ndx Name
25: 00000000 0 FILE LOCAL DEFAULT ABS hello.c
79: 00000000 0 NOTYPE GLOBAL DEFAULT UND crossfunction
80: 00000000 0 FUNC GLOBAL DEFAULT UND printf

最佳答案

从 2.0 版开始,Android 遵循 RTLD_LOCAL 共享库语义。这意味着库中的符号不​​可用于随后加载的库。你必须把你的主程序变成一个 .so 库并将它链接到 libhelloworld.so 显式。参见 this thread了解更多信息。

请注意,Android 动态链接器与 Linux 不同。请务必在不同版本的模拟器(从 Api 3 开始)上测试您的应用,因为机制会随着时间而改变。

关于Android动态链接库无法解析主程序符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7212408/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com