我想看看是否可以在ARM交叉编译器中使用gcc插件(ARM-none eabi-gcc)。然而,我遇到了编译器错误,并质疑我尝试做的事情是否可行。
我尝试设置的插件是:https://github.com/vanhauser-thc/AFLplusplus/tree/master/gcc_plugin
我使用-m32
标志在x86-64 linux上编译插件,因为交叉编译器是一个32位的应用程序。然而,当我尝试在使用-fplugin
的交叉编译器中使用该插件时,我得到了一个未定义的符号编译器错误:
cc1plus: error: cannot load plugin ../afl-gcc-pass.so
../afl-gcc-pass.so: undefined symbol: _Z13build_int_cstP9tree_nodel
我使用nm
查看了插件的符号,发现大多数符号都是未定义的,包括像exit
和random
这样的符号。我对这方面的大部分内容都是新手,不确定这到底意味着什么。一些在线搜索表明,这可能与不正确的库路径有关,但设置LIBRARY_PATH
和LD_LIBRARY_PATH
以及重建似乎没有帮助。
我尝试过的gcc版本设置:
1:x86:5.4.0,臂:5.4.1在ubuntu 16.04 上
2:x86:5.2.0,arm:5.2.1在CentOS 6.8 上
有没有可能在与编译时不同的gcc中使用gcc插件,或者我在浪费时间?
是的,可以用给定的编译器构建一个gcc插件,然后在另一个编译器(包括交叉编译器)中使用该插件,但在构建插件时必须确保包含正确的头文件。具体来说,您必须包含目标编译器的插件开发头文件,而不是主机编译器的那些。目标编译器的插件开发文件所在的目录可以通过以下命令获得:
$(TARGET_CC) -print-file-name=plugin
其中$(TARGET_CC)
是您的目标编译器。因此,在构建插件时,在编译器标志中指定相关include目录的一种简洁方法类似于-I"$(shell $(TARGET_CC) -print-file-name=plugin)/include"
。
对于您尝试使用的特定插件(afl-fuzz的插入),为了为交叉编译器构建插件,您可以修改gcc_plugin文件夹中的Makefile;更具体地说,您可以定义一个包含交叉编译器路径的TARGET_CC
变量,然后在PLUGIN_FLAGS
的定义中将$(CC)
替换为$(TARGET_CC)
,如:
PLUGIN_FLAGS = -fPIC -fno-rtti -I"$(shell $(TARGET_CC) -print-file-name=plugin)/include"
您还必须注释掉在test_build
Makefile目标中执行的命令,因为这些命令会尝试将插件与本机编译器一起使用,因此会失败。然后,您将能够在交叉编译器中使用该插件,如:
arm-none-eabi-gcc -fplugin=../afl-gcc-pass.so --specs=nosys.specs my_source_file.c