gccarmcross-compilinggcc-plugins

Using gcc plugins with cross compiler, undefined symbol


I'm trying to see if it's possible to use a gcc plugin in an ARM cross compiler (arm-none-eabi-gcc). I'm running into compiler errors however, and am questioning whether what I'm trying to do is possible.

The plugin I'm trying to set up is: https://github.com/vanhauser-thc/AFLplusplus/tree/master/gcc_plugin

I'm compiling the plugin on x86-64 linux using the -m32 flag, since the cross compiler is a 32-bit application. However when I try to use the plugin in the cross compiler using -fplugin , I get an undefined symbol compiler error:

cc1plus: error: cannot load plugin ../afl-gcc-pass.so ../afl-gcc-pass.so: undefined symbol: _Z13build_int_cstP9tree_nodel

I looked through the plugin's symbols using nm and discovered that the majority of symbols are undefined, including ones like exit and random. I'm new to most of this and am unsure of what that really means. Some searching online suggested that it may have had something to do with incorrect library paths, but setting LIBRARY_PATH and LD_LIBRARY_PATH and rebuilding did not seem to help.

The gcc version set-ups I have tried:

1: x86: 5.4.0 , arm: 5.4.1 on ubuntu 16.04

2: x86: 5.2.0 , arm: 5.2.1 on CentOS 6.8

Is it possible to use a gcc plugin in a different gcc than it was compiled with or am I wasting my time?


Solution

  • Yes, it is possible to build a gcc plugin with a given compiler and then use the plugin in another compiler (including a cross-compiler), but you have to make sure you include the right header files when building the plugin. Specifically, you have to include the plugin development header files of the target compiler, instead of those of the host compiler. The directory where plugin development files for your target compiler are located can be obtained with the following command:

    $(TARGET_CC) -print-file-name=plugin
    

    where $(TARGET_CC) is your target compiler. So a concise way to specify the relevant include directory in the compiler flags when building the plugin would be something like -I"$(shell $(TARGET_CC) -print-file-name=plugin)/include".

    For the specific plugin you are trying to use (instrumentation for afl-fuzz), in order to build the plugin for your cross-compiler you could modify the Makefile in the gcc_plugin folder; more specifically, you could define a TARGET_CC variable containing the path to your cross-compiler, and then replace $(CC) with $(TARGET_CC) in the definition of PLUGIN_FLAGS, as in:

    PLUGIN_FLAGS = -fPIC -fno-rtti -I"$(shell $(TARGET_CC) -print-file-name=plugin)/include"
    

    You will also have to comment out the commands executed in the test_build Makefile target, because those commands would try to use the plugin with the native compiler and so would fail. Then, you will be able to use the plugin with your cross-compiler, as in:

    arm-none-eabi-gcc -fplugin=../afl-gcc-pass.so --specs=nosys.specs my_source_file.c