使用带有交叉编译器的 gcc 插件,未定义的符号
Using gcc plugins with cross compiler, undefined symbol
我正在尝试查看是否可以在 ARM 交叉编译器 (arm-none-eabi-gcc) 中使用 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 , arm: 5.4.1 on ubuntu 16.04
2: x86: 5.2.0 , arm: CentOS 6.8 上的 5.2.1
是否可以在与编译时不同的 gcc 中使用 gcc 插件,或者我是在浪费时间吗?
是的,可以使用给定的编译器构建 gcc 插件,然后在另一个编译器(包括交叉编译器)中使用该插件,但是您必须确保在构建时包含正确的头文件插入。
具体来说,您必须包含 target 编译器的插件开发头文件,而不是主机编译器的那些。目标编译器的插件开发文件所在目录可以通过以下命令获取:
$(TARGET_CC) -print-file-name=plugin
其中 $(TARGET_CC)
是您的目标编译器。因此,在构建插件时在编译器标志中指定相关包含目录的简洁方法类似于 -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
我正在尝试查看是否可以在 ARM 交叉编译器 (arm-none-eabi-gcc) 中使用 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 , arm: 5.4.1 on ubuntu 16.04
2: x86: 5.2.0 , arm: CentOS 6.8 上的 5.2.1
是否可以在与编译时不同的 gcc 中使用 gcc 插件,或者我是在浪费时间吗?
是的,可以使用给定的编译器构建 gcc 插件,然后在另一个编译器(包括交叉编译器)中使用该插件,但是您必须确保在构建时包含正确的头文件插入。 具体来说,您必须包含 target 编译器的插件开发头文件,而不是主机编译器的那些。目标编译器的插件开发文件所在目录可以通过以下命令获取:
$(TARGET_CC) -print-file-name=plugin
其中 $(TARGET_CC)
是您的目标编译器。因此,在构建插件时在编译器标志中指定相关包含目录的简洁方法类似于 -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