Getting started with GCC plugins - gcc

So after searching the web for a while, Ive decided to try here as it seems to be a good forum for discussion. Im trying to create a simple gcc plugin. The program code is attached in the end of this mail, but in plain english it registers the plugin and makes sure that the pragma_init function is called when pragmas are registered. It is here that I use c_register_pragma to intercept some of the pragmas.
I compile it using the example in http://gcc.gnu.org/onlinedocs/gccint/Plugins-building.html#Plugins-building. The compilation and linking works fine. However, when I load the plug-in I get:
gcc -c -fplugin=plugin.so test.c -o test.o
cc1: error: cannot load plugin plugin.so
plugin.so: undefined symbol: warning
What am I doing wrong? In addition, when including some header files (that will be required later), I get a lot of errors. For example, including "tree.h" yields (amongst 50 other errors):
/machmode.h:262:1: error: unknown type name 'class'
class bit_field_mode_iterator
^
/machmode.h:263:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
{
^
/plugin/include/tree.h:27:0,
from conftest.c:63:
/vec.h:220:8: error: field 'register_overhead' declared as a function
Anyone have a clue on what I am doing wrong?
Thank you

There are two problems here :
The error : "cannot load plugin plugin.so" means that you should add to your LD_LIBRARY_PATH the directory where you store your new shared library plugin.
The hundreds of errors you got with all the files in the include are resolved in my computer if you compile with g++ instead of gcc (not sure to understand why thought)

Which version of GCC are you using, both to compile your plugin, and to use the plugin? Run simply
gcc -v
without any other program argument to find out!
Did you install the appropriate package for GCC plugin development (on Debian or Ubuntu, it might be gcc-4.7-plugin-dev, but adapt the 4.7 version to your particular version of GCC)?
Did you install all the dependencies needed to build your GCC (on Debian or Ubuntu, apt-get build-dep gcc-4.7 gcc-4.7-plugin-dev)?
Recent versions of GCC (notably many GCC 4.7 shipped by distributions, and all GCC 4.8) are compiled by a C++ compiler, not a C compiler.
You may check how was your GCC built (in C or in C++) by running
nm -D -C $(gcc -print-file-name=cc1)
If that command shows typed C++ manged names, e.g. execute_ipa_pass_list(opt_pass*) instead of just execute_ipa_pass_list your GCC has been compiled with a C++ compiler (probably g++)
So you may need to use g++ (not gcc) to compile your GCC plugin.
As I commented, did you consider using MELT (a domain specific language to extend GCC) to extend or customize your gcc compiler?
I suggest downloading the very latest http://gcc-melt.org/melt-plugin-snapshot.tar.bz2 since I will release the next MELT in a few weeks for GCC 4.7 and 4.8
And don't expect to change the parsing behavior of your GCC with a plugin. That is not really possible (GCC provides only plugin hooks to add your builtins and pragmas, not to extend the parsed syntax).

Related

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?
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

Why do I get linker errors when I build a CMake project using Drake, but I can clearly see the symbols?

I have followed the Installation and Quickstart instructions, and am writing a CMake project to use Drake.
I'm looking at a unittest that builds in Drake, run it, and it builds, runs, and passes. However, when I try to use some of that functionality in my CMake project, I get a linker error, such as:
undefined reference to `RigidBodyTree<double>::get_position_name(int) const'
If I look at symbols in the Drake shared library (e.g. nm -C or objdump -TC with grep), I see the signature RigidBodyTree<double>::get_position_name[abi:cxx11](int). However, if I look in the produced object code (which causes the linking to fail), I see RigidBodyTree<double>::get_position_name(int).
(Note: This post is a means to migrate from http://drake.mit.edu/faq.html to StackOverflow for user-based questions.)
This is most likely due to an incompatibilty between the compiler used to produce Drake (e.g. clang) and the compiler that CMake has selected (e.g. gcc-4.9). Specifically, gcc-4.9 or before does not tend to handle the DualABI well when linking against clang-compiled code (ref). You may be able to use other functions, because only functions that return an ABI-dependent class (e.g. std::string) are tagged with the ABI that they are using (since they cannot be distinguished in the function signature).
The fix is to change the compiler CMake is using. One way to do this is to set the CC and CXX environment variables to use a supported compiler. For a list of supported compilers, see Supported Configurations. If you are using pre-compiled binaries, please refer to Binary Packages for the compilers used.
WARNING: Do NOT change the compiler using update-alternatives in Ubuntu, as this may affect your DKMS module compatibility with the kernel (among other things) (ref).

How do I cross compile a static library built on the target with static linkage using c++11 utilities

**Edit: Found my problem. As explained by the following answer, I was not actually doing any linking when making the static library. Instead, I made a shared library and linked libstdc++ statically.
Compile a static library link with standard library (static)**
I am trying to create a method to use c++11 on an ancient arm platform running kernel (2.6.37). Unfortunately the latest cross compile our BSP contains is GCC 4.5.3, which does not support all the c++11 utilites we need.
Initially I tried to use old versions of crosstool-ng to build a cross compiler, but the older versions were too broken. The newer versions did not support the 2.6.37 kernel. I was able to complete one build, however the g++ binary was not built, making the whole endeavor useless (I did check that c++ was enabled in the menuconfig).
Thus my last option was to build gcc natively at version 4.9.4 and create a statically linked library to have my gcc 4.5.3 cross compiler link against. This seems to work for the most part. I create my library on the target with the following:
g++ -std=c++11 --static -c main2.cpp
ar -cvq libmain2.a main2.o
I then copy over the files and try build on the host machine with gcc 4.5.3 and get the following:
arm-angstrom-linux-gnueabi-g++ simple.cpp -lmain2 -L.
(I cleaned up some of the output)
undefined reference to `std::_Hash_bytes(void const*, unsigned int, unsigned int)'
undefined reference to
std::__throw_regex_error(std::regex_constants::error_type)'
However, when I use nm, I get the following:
$ arm-angstrom-linux-gnueabi-nm libmain2.a | grep Hash_bytes
U _ZSt11_Hash_bytesPKvjj
U _ZSt11_Hash_bytesPKvjj
$ arm-angstrom-linux-gnueabi-nm libmain2.a | grep throw_regex
U _ZSt19__throw_regex_errorNSt15regex_constants10error_typeE
U _ZSt19__throw_regex_errorNSt15regex_constants10error_typeE
Does anyone know what the heck is going on? Unfortunately we need to be able to use our cross compiler on the host system for most work, but we are also needing to integrate this specific library which uses c++11.
Also note that if I take out the regex and hash functionality from my code but leave other c++11 concepts like nullptr, type inference, delegation etc, the code compiles and runs on the target fine.
Edit: Okay, so after a little more investigation, it looks like the functions _Hash_bytes and __throw_regex_error are not being statically linked into the static library. I guess I need to know why this is the case in order to fix the issue.

macOS Sierra CoreFoundation error while compiling wxWidgets for SimSpark

I am trying to to compile wxWidgets 3.0.2 found here.
I need this library, so that I can compile SimSpark.
I have tried installing the library via MacPorts - this does work. But when I try to compile SimSpark, the compiler states the following:
In file included from /opt/local/include/gcc49/c++/type_traits:35:0,
from /opt/local/Library/Frameworks/wxWidgets.framework/Versions/wxWidgets/3.0/include/wx-3.0/wx/strvararg.h:25,
from /opt/local/Library/Frameworks/wxWidgets.framework/Versions/wxWidgets/3.0/include/wx-3.0/wx/string.h:46,
from /opt/local/Library/Frameworks/wxWidgets.framework/Versions/wxWidgets/3.0/include/wx-3.0/wx/memory.h:15,
from /opt/local/Library/Frameworks/wxWidgets.framework/Versions/wxWidgets/3.0/include/wx-3.0/wx/object.h:19,
from /opt/local/Library/Frameworks/wxWidgets.framework/Versions/wxWidgets/3.0/include/wx-3.0/wx/event.h:16,
from /Users/YEED/Downloads/simspark-0.2.4/plugin/inputwx/inputwx.cpp:23:
/opt/local/include/gcc49/c++/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
I believe that I need to compile wxWidgets with C++11 support, since I already included the C++11 relevant flags when making SimSpark.
When I try to compile wxWidgets, I get a bunch of compiler errors that refer to the same .h file - which is part of CoreFoundation:
In file included from /usr/include/Availability.h:184:0,
from /usr/include/stdlib.h:61,
from /usr/include/assert.h:44,
from ../include/wx/debug.h:13,
from ../include/wx/defs.h:743,
from ../include/wx/wxprec.h:12,
from ../src/common/filefn.cpp:20:
/System/Library/Frameworks/CoreFoundation.framework/Headers/CFDateFormatter.h:53:34: error: expected '}' before '__attribute__'
kCFISO8601DateFormatWithYear API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) = (1UL << 0),
When you look into that specific file, there are a bunch of lines that miss a closing ) and resemble the one printed by the compiler as well. (There should be a closing ) before the comma at the end of the line, right?)
So my question is, is this an actual error in CoreFoundation? If so, how can I fix this or work around it? Or am I actually completely misunderstanding the compiler error thrown when compiling SimSpark in the first place?
EDIT:
I couldn't get wxWidgets to compile, but I have fixed my issues compiling SimSpark with the MacPorts version of wxWidgets. The problem lay within using different compilers (gcc and clang) for the two.

GCC 4.7, including <stdatomic.h>

I've just compiled GCC 4.7 to work with stdatomic.h, but I can't seem to -I it. stdatomic.h seems to live in /usr/include/c++/4.4.3, but then the linker tells me it needs a bunch of other files in dirs nearby. If I -I all of them, I still get the error undefined reference to atomic_flag_clear_explicit. Any ideas how I'm supposed to link this right?
First, if you are compiling with GCC 4.7 you should not be including or linking anything from a directory from GCC 4.4.
Second, -I only affects the search path for header files. "undefined reference" is a linker error and usually means it hasn't found the right library. You change the library search path with -L. The linker didn't say it didn't find a library with the right name, it says it didn't find a symbol, so clearly the library it did find didn't have that symbol. I'd suggest you have a versioning problem, perhaps caused by a installation problem.
The <stdatomic.h> header in GCC 4.4 and 4.5 was from an early draft of C++0x atomics, but is not part of the final standard, so it was removed from libstdc++.
The C++ compiler supports C++11 atomics via the C++11 <atomic> header, so you should use that header in C++ code.
When the C compiler supports C11 atomics, the <stdatomic.h> header will be provided again.
Using this command solved the problem for me:
$ scl enable devtoolset-7 bash
I got the same error as you when entering sudo make altinstall for installing Python 3.8.5 on CentOS 7.

Resources