基于符号评估两个二进制文件的兼容性。
项目描述
Symbolator
Symbolator是一个小型库,允许您评估符号是否在感兴趣的库和二进制文件之间兼容。目标是创建一个用于build-abi-containers的测试器。
使用方法
安装
您可以在本地安装
$ git clone git@github.com:buildsi/symbolator.git
$ cd symbolator
$ pip install -e .
或从PyPI安装
$ pip install symbolator-python
生成符号
如果您只想为库生成ELF符号(pyelftools),您可以这样做
$ symbolator generate <library>
例如
$ symbolator generate libtcl8.6.so
...
symbol("socket@@GLIBC_2.2.5").
symbol_type("/home/vanessa/Desktop/Code/symbolator/libtcl8.6.so","socket@@GLIBC_2.2.5","FUNC").
symbol_version("/home/vanessa/Desktop/Code/symbolator/libtcl8.6.so","socket@@GLIBC_2.2.5","").
symbol_binding("/home/vanessa/Desktop/Code/symbolator/libtcl8.6.so","socket@@GLIBC_2.2.5","GLOBAL").
symbol_visibility("/home/vanessa/Desktop/Code/symbolator/libtcl8.6.so","socket@@GLIBC_2.2.5","DEFAULT").
symbol_definition("/home/vanessa/Desktop/Code/symbolator/libtcl8.6.so","socket@@GLIBC_2.2.5","UND").
has_symbol("/home/vanessa/Desktop/Code/symbolator/libtcl8.6.so","socket@@GLIBC_2.2.5").
has_symbol("/home/vanessa/Desktop/Code/symbolator/libtcl8.6.so","socket@@GLIBC_2.2.5").
如果您想包含系统符号(链接到感兴趣库的库)
$ symbolator generate --system-libs libtcl8.6.so
当前默认输出是ASP,用于clingo,因为这是我们需要的。如果您需要JSON输出
$ symbolator generate --json libtcl8.6.so
或仅包含全局符号的JSON
$ symbolator generate --json --globals libtcl8.6.so
比较库(compare)
如果您有两个不同版本的库,简单的比较将确定是否有任何符号或参数已更改。我们再次将使用pyelftools进行符号提取。为此,我们只需要两个不同版本的“相同”库。让我们先举些例子
$ cd examples/cpp
$ make
来生成
- libmath-v1.so:原始库
- libmath-v2.so:更改后的库
现在让我们运行比较
$ symbolator compare libmath-v1.so libmath-v2.so
...
{
"is_libA": [
"/home/vanessa/Desktop/Code/symbolator/examples/cpp/libmath-v1.so"
],
"is_libB": [
"/home/vanessa/Desktop/Code/symbolator/examples/cpp/libmath-v2.so"
],
"symbol_is_missing": [
"/home/vanessa/Desktop/Code/symbolator/examples/cpp/libmath-v1.so",
"/home/vanessa/Desktop/Code/symbolator/examples/cpp/libmath-v2.so",
"MathLibrary.cpp"
],
"corpus_name_changed": [
"/home/vanessa/Desktop/Code/symbolator/examples/cpp/libmath-v1.so",
"/home/vanessa/Desktop/Code/symbolator/examples/cpp/libmath-v2.so",
"libmath-v1.so",
"libmath-v2.so"
]
}
或者再次只是JSON
$ symbolator compare libmath-v1.so libmath-v2.so --json
评估兼容性(compat)
为了评估兼容性,我们需要
- 一个主要感兴趣的二进制文件
- 一个已知与该二进制文件兼容的库
- 我们想要测试的竞争库
在示例中有不同编译器的示例。例如,让我们构建cpp的示例文件。
$ cd examples/cpp
$ make
这将生成
- math-client:我们感兴趣的主要二进制文件
- libmath-v1.so:一个已知工作的库
- libmath-v2.so:一个竞争库
如果你看示例,竞争库应该不兼容,因为参数类型有变化。我们可能看不到C的情况,但我们应该看到C++的不同的符号(名称字符串)。要运行测试
$ symbolator compat math-client libmath-v1.so libmath-v2.so
% binary : math-client
% working library : libmath-v1.so
% contender library: libmath-v2.so
Missing Symbol Count: 1
Missing Symbols:
['math-client', 'libmath-v2.so', '_ZN11MathLibrary10Arithmetic3AddEdd']
注意,这是示例的正确答案——我们缺少那个符号!默认情况下,这使用is_compatible.lp。如果你只想将符号输出到其他逻辑程序中使用,你可以这样做
$ symbolator compat --dump math-client libmath-v1.so libmath-v2.so
或者获取答案的json
$ symbolator compat --json math-client libmath-v1.so libmath-v2.so
{
"binary": "/home/vanessa/Desktop/Code/symbolator/examples/cpp/math-client",
"library_working": "/home/vanessa/Desktop/Code/symbolator/examples/cpp/libmath-v1.so",
"library_contender": "/home/vanessa/Desktop/Code/symbolator/examples/cpp/libmath-v2.so",
"missing_symbols": [
"/home/vanessa/Desktop/Code/symbolator/examples/cpp/math-client",
"/home/vanessa/Desktop/Code/symbolator/examples/cpp/libmath-v2.so",
"_ZN11MathLibrary10Arithmetic3AddEdd"
],
"count_missing_symbols": "1"
}
再次,这只是在直接从elf获取符号的pyelftools。
Smeagle稳定性模型
截至版本0.0.15,我们支持读取来自Smeagle或gosmeagle的json输出,然后进行更详细的不稳定性模型。假设我们有来自smeagle的两个输出文件,例如在examples/smeagle中,使用gosmeagle生成以下内容
$ cd examples/cpp
$ make
$ cd ../smeagle
$ gosmeagle parse ../cpp/libmath-v1.so --pretty > libmath-v1.so.json
$ gosmeagle parse ../cpp/libmath-v2.so --pretty > libmath-v2.so.json
然后我们可以运行symbolator来使用json进行稳定性测试。
$ symbolator stability-test examples/smeagle/libmath-v1.so.json examples/smeagle/libmath-v2.so.json --detail
Libraries are not stable: 0 missing exports, 2 missing_imports
Missing Imports
---------------
_ZN11MathLibrary10Arithmetic3AddEdd Basic %rdi 0
_ZN11MathLibrary10Arithmetic3AddEdd Basic %rsi 0
这也可以通过编程方式获取json输出。
与库拼接
假设我们还有一个感兴趣的二进制文件,但我们只对检查符号(以及查找任何未定义的)或请求“拼接”一个感兴趣的库的已知依赖感兴趣——我们可以使用“splice”来完成。当只提供一个二进制文件时,它会读取二进制文件,查找所有依赖库,然后输出任何未定义的符号(不应该有任何)。
$ symbolator splice math-client
% binary : math-client
% splice : libmath-v1.so->libmath-v2.so
Missing Symbols:
=> math-client
__gmon_start__
_ITM_deregisterTMCloneTable
_ITM_registerTMCloneTable
...
现在假设我们想要拼接其他版本的libmath。
$ symbolator splice math-client -s libmath-v1.so=libmath-v2.so
如果库的主名称相同(例如,libmath.1.so与libmath.2.so),我们只需这样做
$ symbolator splice math-client -s libmath.2.so
% binary : math-client
% splice : libmath-v1.so->libmath-v2.so
Missing Symbols:
=> math-client
_ZN11MathLibrary10Arithmetic3AddEdd
__gmon_start__
_ITM_deregisterTMCloneTable
_ITM_registerTMCloneTable
使用前缀。但由于前缀有一个不同的名称,我们需要明确地命名它。为了以json格式输出
$ symbolator splice math-client -s libmath.2.so --json
如果我们为拼接和未拼接生成了符号(给定已更改的库),然后我们可以快速地进行比较(跨越所有符号)并发现唯一的区别是更改的库中缺少的符号
[x for x in values if x not in compares]
['_ZN11MathLibrary10Arithmetic3AddEdd']
延迟拼接
如果我们想稍后导出json以进行拼接,我们可以这样做
$ mkdir -p examples/splice
$ cd examples/splice
$ symbolator generate ../cpp/math-client --system-libs --json > math-client.json
$ symbolator generate ../cpp/libmath-v2.so --system-libs --json > libmath-v2.so.json
然后进行类似的拼接,但使用输入json。
$ symbolator jsonsplice math-client.json -s libmath-v1.so=libmath-v2.so.json
或者不进行拼接
$ symbolator jsonsplice math-client.json
输出相同(我们看到缺少的符号),但使用这种方法,我们可以分别运行提取,保存数据,然后在json中稍后进行拼接!
与Smeagle拼接
开发中
请注意,这不会工作,直到smeagle能够处理加载这些库而不发生段错误。练习将类似于以下内容。
如果我们想使用Smeagle事实运行类似的分析,那么我们实际上需要预先生成所有事实,并将它们“扔进汤里”。我们可以通过ldd的发现和生成方式来做到这一点,然后将json交给splice。
$ ldd examples/cpp/math-client
linux-vdso.so.1 (0x00007ffc05b96000)
libmath-v1.so => not found
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f6854aff000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f685490d000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f68547be000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6854d03000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f68547a3000)
从上面的内容我们运行
$ mkdir -p examples/smeagle/global
$ cd examples/smeagle/global
$ gosmeagle parse ../../cpp/libmath-v1.so --pretty > libmath-v1.so.json
$ gosmeagle parse ../../cpp/math-client --pretty > math-client.json
$ gosmeagle parse /lib/modules/5.4.0-89-generic/vdso/vdso64.so --pretty > vdso64.so.json
这些没有dwarf
/usr/lib/x86_64-linux-gnu/libstdc++.so.6
/lib/x86_64-linux-gnu/libc.so.6
/lib64/ld-linux-x86-64.so.2
/lib/x86_64-linux-gnu/libgcc_s.so.1
Smeagle c++也无法解析它们。
# ./build/standalone/Smeagle -l /lib/x86_64-linux-gnu/libgcc_s.so.1
Segmentation fault (core dumped)
测试
安装symbolator后
$ cd tests/
$ ./test_client.sh
容器安装
您还可以将symbolator构建到容器中!
$ docker build -t symbolator .
然后可以通过entrypoint或shell与symbolator交互。
# shell
$ docker run --entrypoint bash -it symbolator
# entrypoint
$ docker run -it symbolator
示例已构建到容器中以方便测试。
$ cd examples/cpp
$ symbolator compat math-client libmath-v1.so libmath-v2.so
% binary : math-client
% working library : libmath-v1.so
% contender library: libmath-v2.so
Compatible
示例
示例文件夹包含了多个编译器的代码,您可以在其中进行测试。
- g++
- gcc
- gcc-10
- icc
- icpc
- clang
- clang-10
- clang++
许可证
此项目是Spack的一部分。Spack采用MIT许可协议和Apache许可协议(版本2.0)进行分发。用户可以选择任一许可协议。
所有新的贡献都必须在MIT和Apache-2.0许可协议下进行。
有关详细信息,请参阅LICENSE-MIT、LICENSE-APACHE、COPYRIGHT和NOTICE。
SPDX-License-Identifier: (Apache-2.0 OR MIT)
LLNL-CODE-811652
项目详情
symbolator-python-0.0.18.tar.gz的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | edff9fe411da22d76b91d757ab85c0c8c55c781a864375b4c05ff04b2f24d8e6 |
|
MD5 | 48f17ea74f1d3684579a3cb0cf1436c8 |
|
BLAKE2b-256 | fbd497091c05e242f4f799a458d7467c9f88a7e8d31c7de8ab743867e52a3c4c |