前言
-
musl 是一个轻量级的标准C库,建立在系统调用之上,可以认为是【用户态】的C 库,与 glibc 或者 uClibc 属于同一类。
-
基于 musl 的 gcc 工具链包括交叉编译工具链,可以用于编译 Linux 或者其他的操作系统,如当前 Lite-OS、RT-Smart 上都采用 musl gcc 作为编译工具链,使用 musl libc作为用户态应用的C 库。
-
musl 基于 MIT 授权,开源、轻量、免费,估计越来越多的操作系统开始采用 musl 作为标准C库
-
最近也一直在研究 musl libc 的 ldso,也就是动态加载功能,musl 的 动态加载功能集成在 musl libc.so 中。
elf 格式文件
-
musl 本身集成了 动态加载 功能 ldso,初步看了代码,发现支持 elf 格式的动态编译的应用程序加载。
-
使用 musl gcc 工具链(交叉编译工具链)编译的应用程序,可以通过
readelf -l xxx.elf
,查看 elf 文件的是否存在动态链接信息,如果包含则需要使用 musl ldso 对依赖的共享库进行加载 -
示例: 查看一个动态链接的应用程序是否存在 【解释器段】信息:
INTERP
类型的
命令:aarch64-linux-musleabi-readelf.exe -l glib_gio_test_s.elf
或者 readelf.exe -l glib_gio_test_s.elf
发现 存在 INTERP
段信息, [Requesting program interpreter: /lib/ld-musl-aarch64.so.1]
查看 elf 文件依赖的共享库
- 静态编译的 elf,没有 动态链接信息,也不依赖 共享库,而动态编译链接的 elf 文件,存在动态链接信息,通过
aarch64-linux-musleabi-readelf.exe -d glib_gio_test_s.elf
或者readelf.exe -d glib_gio_test_s.elf
,可以查看依赖的共享库
查看 elf 的头部信息
- 使用
aarch64-linux-musleabi-readelf.exe -h glib_gio_test_s.elf
或者readelf.exe -h glib_gio_test_s.elf
可以查看应用程序 elf 的头部信息,如获取 入口函数地址等
查看 elf 符号信息
- 所谓 elf 符号,就是一些变量名、函数名、数组等,依旧可以通过
readelf
来查看
aarch64-linux-musleabi-readelf.exe -s glib_gio_test_s.elf
或者 readelf.exe -s glib_gio_test_s.elf
,注意由于有些 应用程序 elf 文件的符号特别多,所以可以输出到一个文本文件,然后使用文件查看工具进行查看
aarch64-linux-musleabi-readelf.exe -s glib_gio_test_s.elf > sym_01.s
,这里 把符号导出到 sym_01.s
文件,然后用文本查看工具打开查看
elf 查看工具
-
以上是 elf 文件 通过
readelf
进行查看,那么还有其他的工具可以查看 elf 文件吗? -
推荐使用 :
EmEditor
二进制查看工具,可以查看、搜索、编辑二进制文件, elf 文件其实也是二进制文件。
-
推荐使用 Die,大名鼎鼎的 Detect It Easy 工具进行 elf 文件的解析查看,可以二进制查看、反汇编、查看 各个段、节等信息
-
使用 die 打开一个 elf 文件
- 使用 die 查看 elf 文件信息: elf 头部
小结
-
本篇主要记录 elf 文件的查看,初步了解一下 要动态加载的 文件,也就是 研究动态加载之前,一定要熟悉 elf 格式的文件,文件组成、文件头部、文件 Program Header,文件的各个段,文件的 节,动态加载需要加载 elf 文件的哪些内容
-
当前了解到, 一个 elf 文件 只有一个 头部、有一个或者多个 Program Header,一个 Program Header 的大小是固定的,也就是一个结构体,里面的内容描述一个 段Segment 信息, 一个 elf 文件有多少个 Program Header? 这个需要通过解析 elf 文件的 头部: elf Header 获取到
-
建议查看 elf 的标准规范,熟悉 elf ,熟悉 elf 组成、加载机制,这样对后面研究动态加载非常重要。