Android源码阅读-dlopen
本次阅读源码来自aosp Android 8.1.0_r1,在阅读过程中根据阅读的进度随手记录
有过 linux
编成经验的都应该知道使用 dlopen
需要包含 dlfcn.h
头文件,所以直接去aosp/bionic/libc/include/dlfcn.h
中找到 dlopen
的函数定义。
1 | void* dlopen(const char* filename, int flag); |
通过dlopen
的定义找到其实现在 aosp/bionic/libdl/libdl.c
中,
1 | // Proxy calls to bionic loader |
可以发现 dlopen
的是通过 __loader_dlopen
完成其实现的。查看 __loader_dlopen
的实现,会发现找不到其是实现方法,只能找到相关的定义 aosp/bionic/libdl/libdl.c
:
1 | __attribute__((__weak__, visibility("default"))) |
通过搜索 __loader_dlopen
字符串,发现 aosp/bionic/linker/dlfcn.cpp
存在相关字符串。
跟进去后发现,其被定义的在 ANDROID_LIBDL_STRTAB
字符串数组中
1 | static const char ANDROID_LIBDL_STRTAB[] = |
继续跟进,发现 g_libdl_symtab
中使用了 ANDROID_LIBDL_STRTAB
1 | static ElfW(Sym) g_libdl_symtab[] = { |
将相关代码复制到一个C源码文件,使用 g++ -E
宏展开并优化后:
1 | static ElfW(Sym) g_libdl_symtab[] = { |
2019-11-17 01:47:00.768 10666-10666/com.example.ndkdebug E/linker: library “/system/lib64/libandroid_runtime.so” (“/system/lib64/libandroid_runtime.so”) needed or dlopened by “/data/app/com.example.ndkdebug-tJLtYCKjLoRt2XhNQlIu9A==/lib/arm64/libnative-lib.so” is not accessible for the namespace: [name=”classloader-namespace”, ld_library_paths=””, default_library_paths=”/data/app/com.example.ndkdebug-tJLtYCKjLoRt2XhNQlIu9A==/lib/arm64:/data/app/com.example.ndkdebug-tJLtYCKjLoRt2XhNQlIu9A==/base.apk!/lib/arm64-v8a”, permitted_paths=”/data:/mnt/expand:/data/data/com.example.ndkdebug”]
未完待续。。。