{"id":133,"date":"2025-06-14T09:18:51","date_gmt":"2025-06-14T09:18:51","guid":{"rendered":"https:\/\/haco.club\/?p=133"},"modified":"2025-06-14T09:18:51","modified_gmt":"2025-06-14T09:18:51","slug":"an-introduction-to-gcc-and-gccs-plugins","status":"publish","type":"post","link":"https:\/\/haco.club\/?p=133","title":{"rendered":"An introduction to GCC and GCC&#8217;s plugins"},"content":{"rendered":"\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><a href=\"https:\/\/gabrieleserra.ml\/blog\/2020-08-27-an-introduction-to-gcc-and-gccs-plugins.html\">https:\/\/gabrieleserra.ml\/blog\/2020-08-27-an-introduction-to-gcc-and-gccs-plugins.html<\/a><\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"1-brief-introduction-to-gnus-gcc\">1.&nbsp;<a><\/a>Brief introduction to GNU\u2019s GCC<\/h2>\n\n\n\n<p>The GNU toolchain is a collection of tools and libraries produced in the context of the GNU project. In 1983, Richard Stallman announced the GNU project. Its goal was to give the community freedom and control in their use of computing devices by developing (collaboratively) free software and letting users modify, copy, and distribute it freely.<\/p>\n\n\n\n<p>The GNU toolchain was part of that software and today includes some of the most widespread tools used to develop and compile application such as:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>GNU make: an automation tool for compilation and build<\/li>\n\n\n\n<li>GNU Compiler Collection (GCC): a suite of compilers for several programming languages<\/li>\n\n\n\n<li>GNU C Library (glibc): core C library including headers, libraries, and dynamic loader<\/li>\n\n\n\n<li>GNU Binutils: a suite of tools including linker, assembler and other tools<\/li>\n\n\n\n<li>GNU Debugger (GDB): a code debugging tool<\/li>\n<\/ul>\n\n\n\n<p>In particular, we will focus on GCC that, maybe, is the main component of the GNU toolchain. In practice, the GNU community placed a lot of effort into developing extensible and modular software to provide other people a way to contribute to the project adding functionalities. The straightforward way is via a plugin, namely providing a way to load a customizable module that interacts with the main module without modifying the project\u2019s source code.<\/p>\n\n\n\n<p>Then, from GCC 4.5.0 (2010), plugin support is available.&nbsp;<a href=\"https:\/\/gcc.gnu.org\/wiki\/plugins\">[1]<\/a><\/p>\n\n\n\n<p>Main advantages:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Shortens build and test for new features because GCC does not need to be re-compiled<\/li>\n\n\n\n<li>Allows development and maintenance of features that can\u2019t take place in GCC\u2019s mainline<\/li>\n\n\n\n<li>Simplifies developers\u2019s work when they have minimal knowledge of compiler internals.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"2-getting-started-hello-world\">2.&nbsp;<a><\/a>Getting started: Hello World!<\/h2>\n\n\n\n<p>The purpose of this section is to introduce you to the world of GCC plugins. The first time I approached to this stuff, I was really surprised because the amount of material available to start with was very poor. Furthermore, the GCC documentation about plugins was really not sufficient to start. Luckily I found an article in LWN that helped me start. It is not update but, if you want to build something for an older version of GCC could be a good starting point&nbsp;<a href=\"https:\/\/lwn.net\/Articles\/457543\/\">[2]<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"21-environment-setup\">2.1.&nbsp;<a><\/a>Environment setup<\/h3>\n\n\n\n<p>A plugin is just a shared library that follows the convention posed by GCC.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>From version 4.8. GCC is completely written in C++&nbsp;<a href=\"http:\/\/www.h-online.com\/news\/item\/GCC-4-8-completes-migration-to-C-1824539.html\">[3]<\/a><\/p>\n<\/blockquote>\n\n\n\n<p>Then we will need to write C++ code. As a C developer, I was a bit scared; however, I found that:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\u201cAccording to a post by Mark Mitchell on the GCC mailing list, however, advanced C++ features such as multiple inheritance, templates and exceptions are to be avoided \u2013 the source code of the GNU Compiler Collection is to remain easily understandable for C programmers and should only include constructs that don\u2019t lend themselves to errors.\u201d&nbsp;<a href=\"http:\/\/www.h-online.com\/open\/news\/item\/GCC-allows-C-to-some-degree-1012611.html\">[4]<\/a>&nbsp;<a href=\"https:\/\/gcc.gnu.org\/legacy-ml\/gcc\/2010-05\/msg00705.html\">[5]<\/a><\/p>\n<\/blockquote>\n\n\n\n<p>So, let\u2019s start to develop! At first, you need all the libraries that contain all necessary symbols to build a GCC plugin. The easiest way to figure out where the include files are located is to run the following command in the console.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>$<\/strong> gcc -print-file-name=plugin\n\/usr\/lib\/gcc\/x86_64-linux-gnu\/9\/plugin<\/code><\/pre>\n\n\n\n<p>If this command simply prints the word \u201cplugin\u201d, \u201c you have no plugin dev libraries installed. Then get your exact GCC version and then install the libraries. In some setups, happens that you have only the folder plugin with .so files but not the development libraries. In that case, you have to install it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>$<\/strong> gcc --version\n<strong>$<\/strong> sudo apt install gcc-X.X-plugin-dev<\/code><\/pre>\n\n\n\n<p>Let\u2019s start creating a directory move inside it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>$<\/strong> mkdir gcc-instrumentation-plugin\n<strong>$<\/strong> cd gcc-instrumentation-plugin\n<strong>$<\/strong> touch main.cpp<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">2.2.\u00a0Introduction to GCC plugin APIs<\/h3>\n\n\n\n<p>The&nbsp;<code>gcc-plugin.h<\/code>&nbsp;must be the&nbsp;<strong>first<\/strong>&nbsp;GCC header to be included.<\/p>\n\n\n\n<p>The&nbsp;<code>gcc-plugin.h<\/code>&nbsp;must be the&nbsp;<strong>first<\/strong>&nbsp;GCC header to be included.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;gcc-plugin.h><\/code><\/pre>\n\n\n\n<p>If your editor\/IDE does not find the header file, it could be in&nbsp;<code>\/usr\/lib\/gcc\/x86_64-linux-gnu\/7\/plugin\/include\/<\/code>. Anyway, as pointed out before, you can run the command&nbsp;<code>gcc -print-file-name=plugin<\/code>&nbsp;to make GCC print the path for you, then search for the include folder. Clearly substitute your GCC version in the path. If you are using&nbsp;<em>Visual Studio Code<\/em>, you can add the directory in&nbsp;<code>includePath<\/code>&nbsp;to suppress include-errors.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"221-plugin-license-check\">2.2.1.&nbsp;<a><\/a>Plugin license check<\/h4>\n\n\n\n<p>Every plugin should define the global symbol&nbsp;<code>plugin_is_GPL_compatible<\/code>. Indeed the GNU community is sensible to keep the software free and shareable, and the symbol serves to assert that the plugin is licensed under a GPL license. If the symbol does not exist, the compiler will output a fatal error with the following message:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>fatal error: plugin name is not licensed under a GPL-compatible license\nname: undefined symbol: plugin_is_GPL_compatible\ncompilation terminated<\/code><\/pre>\n\n\n\n<p>The symbol must be of integer type to match a forward declaration written in&nbsp;<code>gcc-plugin.h<\/code>. However, it does not need to be in any specific section because it is enough that the symbol exists in the global scope for GCC. So let\u2019s define it at the beginning of our file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int plugin_is_GPL_compatible;<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"222-plugin-initialization\">2.2.2.&nbsp;<a><\/a>Plugin initialization<\/h4>\n\n\n\n<p>Each plugin must export a function&nbsp;<code>plugin_init<\/code>&nbsp;called as soon as the plugin is loaded and is responsible for registering all callbacks and stuff required by the plugin. The function is called right before invoking the parser. The function has two arguments:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ if init fails, must return non-zero, otherwise it should return 0\nint plugin_init ( struct plugin_name_args *plugin_info, \/\/ plugin info\n                  struct plugin_gcc_version *version); \/\/ GCC version<\/code><\/pre>\n\n\n\n<p>Both structures, arguments of the function, are defined in the&nbsp;<code>gcc-plugin.h<\/code>. Let\u2019s analyze them in details:<\/p>\n\n\n\n<p><code>struct plugin_name_args<\/code>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Not user-filled, rather a read-only structure<\/li>\n\n\n\n<li>It contains info that GCC got from the plugin<\/li>\n\n\n\n<li>Useful to get arguments passed to the plugin via the command line (we will see better)<\/li>\n<\/ul>\n\n\n\n<p><code>struct plugin_gcc_version<\/code>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>It contains info about current GCC version, revision number and so on<\/li>\n\n\n\n<li>Useful to ensure your plugin operates on the appropriate version of GCC<\/li>\n<\/ul>\n\n\n\n<p>Let\u2019s extract them from the&nbsp;<code>.h<\/code>&nbsp;file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/* Object that keeps track of the plugin name and its arguments. *\/\nstruct plugin_name_args\n{\n  char *base_name;              \/* Name of the plugin (file w\/o .so suffix) *\/\n  const char *full_name;        \/* Plugin path as specified with -fplugin=. *\/\n  int argc;                     \/* Num of args specified with -fplugin-arg- *\/\n  struct plugin_argument *argv; \/* Array of ARGC key-value pairs. *\/\n  const char *version;          \/* Version string provided by plugin. *\/\n  const char *help;             \/* Help string provided by plugin. *\/\n}\n\n\/* Represents the gcc version. Used to avoid using an incompatible plugin. *\/\nstruct plugin_gcc_version\n{\n  const char *basever;\n  const char *datestamp;\n  const char *devphase;\n  const char *revision;\n  const char *configuration_arguments;\n};<\/code><\/pre>\n\n\n\n<p>Well, coming back to the \u2018plugin_init\u2019 function, the most straightforward way of implementing it is to use the&nbsp;<code>plugin_default_version_check<\/code>, which compares field by field two&nbsp;<code>plugin_gcc_version<\/code>&nbsp;structures.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include \"plugin-version.h\"\n\/\/ ...\n\n\/** Returns 0 if initialization finishes successfully. *\/\nint plugin_init ( struct plugin_name_args *plugin_info,\n                  struct plugin_gcc_version *version)\n{\n  if (!plugin_default_version_check (version, &amp;gcc_version))\n    return 1;\n  return 0;\n}<\/code><\/pre>\n\n\n\n<p>The GCC version used to compile the plugin can be found in the symbol&nbsp;<code>gcc_version<\/code>&nbsp;defined in the header&nbsp;<code>plugin-version.h<\/code>. Of course, if you want a less strict check, you can implement your own comparison routine. We will stick for the simplest version.<\/p>\n\n\n\n<p>If&nbsp;<code>plugin_init<\/code>&nbsp;returns 1, you will experiment a&nbsp;<code>cc1: error: fail to initialize plugin<\/code>&nbsp;during the compilation of the target program.<\/p>\n\n\n\n<p>Furthermore, we can include some public information to developers that use our plugin using the&nbsp;<code>plugin_info<\/code>&nbsp;structure. In case the user asks for help (via&nbsp;<code>gcc --help<\/code>) or want to know the version (via&nbsp;<code>gcc --version<\/code>), the information present in the structure will be printed out.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/* Additional information about the plugin. Used by --help and --version. *\/\nstruct plugin_info\n{\n  const char *version;\n  const char *help;\n};<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"223-plugin-callbacks\">2.2.3.&nbsp;<a><\/a>Plugin callbacks<\/h4>\n\n\n\n<p>Callbacks are the simplest way to interact with GCC while it is doing its work! We can make GCC call one of our function when a specific event occurs. Here is the list of possible events that could trigger a callback.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>enum plugin_event\n{\n  PLUGIN_START_PARSE_FUNCTION,      \/* Called before parsing the body of a func. *\/\n  PLUGIN_FINISH_PARSE_FUNCTION,     \/* After finishing parsing a function. *\/\n  PLUGIN_PASS_MANAGER_SETUP,        \/* To hook into pass manager. *\/\n  PLUGIN_FINISH_TYPE,               \/* After finishing parsing a type. *\/\n  PLUGIN_FINISH_DECL,               \/* After finishing parsing a declaration. *\/\n  PLUGIN_FINISH_UNIT,               \/* Useful for summary processing. *\/\n  PLUGIN_PRE_GENERICIZE,            \/* Allows to see low level AST in frontends. *\/\n  PLUGIN_FINISH,                    \/* Called before GCC exits. *\/\n  PLUGIN_INFO,                      \/* Information about the plugin. *\/\n  PLUGIN_GGC_START,                 \/* Called at start of GCC Garbage Collection. *\/\n  PLUGIN_GGC_MARKING,               \/* Extend the GGC marking. *\/\n  PLUGIN_GGC_END,                   \/* Called at end of GGC. *\/\n  PLUGIN_REGISTER_GGC_ROOTS,        \/* Register an extra GGC root table. *\/\n  PLUGIN_ATTRIBUTES,                \/* Called during attribute registration. *\/\n  PLUGIN_START_UNIT,                \/* Called before processing translation unit. *\/\n  PLUGIN_PRAGMAS,                   \/* Called during pragma registration. *\/\n  PLUGIN_ALL_PASSES_START,          \/* Called before first pass from all_passes. *\/\n  PLUGIN_ALL_PASSES_END,            \/* Called after last pass from all_passes. *\/\n  PLUGIN_ALL_IPA_PASSES_START,      \/* Called before first ipa pass. *\/\n  PLUGIN_ALL_IPA_PASSES_END,        \/* Called after last ipa pass. *\/\n  PLUGIN_OVERRIDE_GATE,             \/* Allows to override pass gate decision for current_pass. *\/\n  PLUGIN_PASS_EXECUTION,            \/* Called before executing a pass. *\/\n  PLUGIN_EARLY_GIMPLE_PASSES_START, \/* Called before subpasses of a GIMPLE_PASS in execute_ipa_pass_list. *\/\n  PLUGIN_EARLY_GIMPLE_PASSES_END,   \/* Called after subpasses of a GIMPLE_PASS in execute_ipa_pass_list. *\/\n  PLUGIN_NEW_PASS,                  \/* Called when a pass is first instantiated. *\/\n  PLUGIN_INCLUDE_FILE,              \/* Called when a file is #include-d or given via the #line directive. *\/\n  PLUGIN_EVENT_FIRST_DYNAMIC        \/* Dummy event used for indexing callback array.  *\/\n};<\/code><\/pre>\n\n\n\n<p>I have used only a restricted subset of these events. However, I think they cover a lot of practical situations. Furthermore, plugins can also interact with the enumerator of events and generate new events dynamically. Honestly, I had\u2019t tried yet, so please refer to the GCC documentation.<\/p>\n\n\n\n<p>Now the question is how to register how plugin to being called when one of these events occurs? In practice, we have to use the function&nbsp;<code>register_callback<\/code>&nbsp;(and the dual&nbsp;<code>unregister_callback<\/code>&nbsp;if we need to de-register our plugin).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void register_callback (const char *plugin_name,\n\t\t\t                  int event,\n                        plugin_callback_func callback,\n                        void *user_data\n                        );<\/code><\/pre>\n\n\n\n<p>where the arguments are:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>char *name<\/code>: The plugin name<\/li>\n\n\n\n<li><code>int event<\/code>\u00a0: The event code taken from the enum above<\/li>\n\n\n\n<li><code>plugin_callback_func callback<\/code>: The function of the plugin that handles event<\/li>\n\n\n\n<li><code>void *user_data<\/code>: Pointer to plugin-specific data passed as input to the function<\/li>\n<\/ul>\n\n\n\n<p>Things become a little more interesting when we analyze the type&nbsp;<code>plugin_callback_func<\/code>&nbsp;that is a pointer to a function representing the function type needed to be a callback routine candidate.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/* Function type for a plugin callback routine.\n\n   GCC_DATA  - event-specific data provided by GCC\n   USER_DATA - plugin-specific data provided by the plugin  *\/\n\ntypedef void (*plugin_callback_func) (void *gcc_data, void *user_data);<\/code><\/pre>\n\n\n\n<p>The problem here is that no one knows what&nbsp;<code>gcc_data<\/code>&nbsp;contains for each event and is not documented anywhere! The same is true for&nbsp;<code>user_data<\/code>. Except for a few events, you have to proceed to try debugging or seek the GCC internals. For several, I already had the answer you need!<\/p>\n\n\n\n<p>For our first example, we will register our plugin to the event&nbsp;<code>PLUGIN_INFO<\/code>, where the callback function should be&nbsp;<code>NULL<\/code>, and the&nbsp;<code>user_data<\/code>&nbsp;is the&nbsp;<code>plugin_info<\/code>&nbsp;structure.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"23-compiling-and-loading-plugins-onto-gcc\">2.3.&nbsp;<a><\/a>Compiling and loading plugins onto GCC<\/h3>\n\n\n\n<p>As I pointed out before, plugins are shared libraries. They are loaded by the compiler using&nbsp;<code>dlopen<\/code>&nbsp;on Linux (or the equivalent DLL open on Windows) and invoked when needed during the compilation process. Our reference OS is Ubuntu, so I will consider only&nbsp;<code>.so<\/code>&nbsp;libraries, but I hope won\u2019t be a problem for those who use Windows.<\/p>\n\n\n\n<p>To obtain a suitable GCC plugin, you simply have to adhere to GCC APIs and compile it as a shared library. Ok, this is not true; when you need to register to GCC passes (we will see what they are), you have to take care of passing&nbsp;<code>-fno-rtti<\/code>&nbsp;option. I don\u2019t remember even how I find it\u2026 for sure caused me a severe headache.&nbsp;<a href=\"https:\/\/gcc.gnu.org\/legacy-ml\/gcc-patches\/2013-07\/msg01258.html\">[6]<\/a><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><code>-fno-rtti<\/code>&nbsp;disables generation of information about every class with virtual functions for use by the C++ runtime type identification features. If you don\u2019t use those parts of the language, you can save some space by using this flag. GCC itself is built with -fno-rtti. Hence plugins that create passes will need to be built with RTTI disabled in order to link against gcc, or they will fail to load.&nbsp;<a href=\"https:\/\/gcc.gnu.org\/onlinedocs\/gcc-4.4.7\/gcc\/C_002b_002b-Dialect-Options.html\">[7]<\/a><\/p>\n<\/blockquote>\n\n\n\n<p>In the example, at the end of the chapter, I will provide a ready-to-use makefile.<\/p>\n\n\n\n<p>Let\u2019s go ahead. In practice, when we need to use a plugin, we have to inform GCC to load it using the option:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>-fplugin=\/path\/to\/lib.so -fplugin-arg-name-key1&#91;=value1]<\/code><\/pre>\n\n\n\n<p>where the option&nbsp;<code>-fplugin<\/code>&nbsp;takes the path to the shared library with the extension. Also you can pass arguments to GCC using key-value pairs. Note that you can specify more than one plugin using multiple -fplugin arguments and, of course, multiple arguments to plugins.<\/p>\n\n\n\n<p>You can also provide the short name of the plugin (with no dots nor slashes) only if the plugin is placed in the plugin directory (and you can figure out the location of the default plugin directory using the command we have seen so far&nbsp;<code>gcc -print-file-name=plugin<\/code>).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"24-complete-hello-world-example\">2.4.&nbsp;<a><\/a>Complete \u2018hello world!\u2019 example<\/h3>\n\n\n\n<p>Great! Let\u2019s write out our complete&nbsp;<code>main.cpp<\/code>&nbsp;to realize our \u201chello-world\u201d example!<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Here you can find the raw files:&nbsp;<a href=\"https:\/\/gabrieleserra.ml\/assets\/postdata\/an-introduction-to-gcc-and-gccs-plugins\/hello-world\/\">hello-world<\/a><\/p>\n<\/blockquote>\n\n\n\n<p><strong>main.cpp<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include \"plugin-version.h\"\n\nint plugin_is_GPL_compatible;\n\n\/* Additional information about the plugin. Used by --help and --version. *\/\nstatic struct plugin_info inst_plugin_info =\n{\n  .version = \"0.1\",\n  .help = \"Currently I am not able to help you!\",\n};\n\n\/* Represents the gcc version we need. Used to void using an incompatible plugin. *\/\nstatic struct plugin_gcc_version inst_plugin_ver =\n{\n  .basever = \"9.2.1\",\n};\n\n\/** Returns 0 if initialization finishes successfully. *\/\nint plugin_init ( struct plugin_name_args *plugin_info,\n                  struct plugin_gcc_version *version)\n{\n  if (strncmp(inst_plugin_ver.basever, version->basever, strlen(version->basever)))\n    return 1;\n\n  \/\/ tell to GCC some info about the plugin\n  register_callback(\"inst_plugin\", PLUGIN_INFO, NULL, &amp;inst_plugin_info);\n\n  printf(\"Hello world!\\n\");\n  \n  \/\/ done!\n  return 0;\n}<\/code><\/pre>\n\n\n\n<p>Then we need a target c program to compile with GCC and then to test our plugin! We can write an elementary program that does all but printing something to the standard output.<\/p>\n\n\n\n<p><strong>target.c<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h>\n\nint main()\n{\n  printf(\"I'm a target C program.\\n\");\n  return 1;\n}<\/code><\/pre>\n\n\n\n<p>Finally, we can use a Makefile to compile our GCC plugin. (If you experiment a&nbsp;<code>missing separator<\/code>&nbsp;error, keep attention to tab-width)<\/p>\n\n\n\n<p><strong>Makefile<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># The gcc used to compile our plugin (consider that is written in C++!)\nHOST_GCC = g++\n\n# The gcc that will support our plugin \nTARGET_GCC = gcc\n\n# The name of the file we want to compile \nPLUGIN_SOURCE_FILES = main.cpp\n\n# Plugins directory of GCC\nGCC_PLUGINS_DIR = $(shell $(TARGET_GCC) -print-file-name=plugin)\n\n# GCC CPP flags (we need position-independent code and run-time type info support disabled)\nCXXFLAGS+= -I$(GCC_PLUGINS_DIR)\/include -fPIC -fno-rtti\n\n# our recipes\n.PHONY: all clean test\n\nall: inst_plugin.so\n\ninst_plugin.so: $(PLUGIN_SOURCE_FILES)\n\t$(HOST_GCC) -shared $(CXXFLAGS) $^ -o $@\n\ntest: inst_plugin.so\n\tgcc target.c -fplugin=$(shell pwd)\/inst_plugin.so -o bin\n\nclean: \n\trm -f inst_plugin.so bin<\/code><\/pre>\n\n\n\n<p>Ok, let\u2019s try to compile the target program with our brand new plugin.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>$<\/strong> make\n<strong>$<\/strong> gcc target.c -fplugin=`pwd`\/inst_plugin.so -o bin\nHello world! <\/code><\/pre>\n\n\n\n<p><code>Hello world!<\/code>&nbsp;will be printed out during compilation! Great! The same is valid if you ask for help or for GCC version, your define properties will be printed<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>$<\/strong> gcc -fplugin=`pwd`\/inst_plugin.so --verbose --help\n...\nVersions of loaded plugins:\n inst_plugin: 0.1\nHelp for the loaded plugins:\n inst_plugin:\n    Currently I am not able to help you!\n...<\/code><\/pre>\n\n\n\n<p>I have also provided a target&nbsp;<code>test<\/code>&nbsp;in the makefile to run&nbsp;<code>make test<\/code>&nbsp;and check the output of your plugin directly during the compilation of a target program. We have finished for this first \u201cHello world\u201d example.<\/p>\n\n\n\n<p>If you arrived here and need something more, it means you are really interested in the topic. Let\u2019s go ahead.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"3-instrumenting-a-function-for-debugging-or-monitoring\">3.&nbsp;<a><\/a>Instrumenting a function for debugging or monitoring<\/h2>\n\n\n\n<p>Now, let\u2019s jump directly to our objective. We want to instrument the code we are compiling with a function on each function call. Reasons could be many, maybe we want to track the flow of execution of our program, perhaps we are facing a tricky bug, and we want to figure out what is going on, or maybe we just want to be sure our program is following the intended flow.<\/p>\n\n\n\n<p>We have lots of possible choices, we will start with the simplest one!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"31-instrument-code-with-gcc-compiling-options\">3.1.&nbsp;<a><\/a>Instrument code with GCC compiling options<\/h3>\n\n\n\n<p>At first, we could just take advantage of the options available when compiling with GCC. Actually, if we don\u2019t need anything special, we could just stick with&nbsp;<code>-finstrument-functions<\/code>&nbsp;or&nbsp;<code>-fpatchable-function-entry<\/code>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"311-gcc-option--finstrument\">3.1.1.&nbsp;<a><\/a>GCC option: -finstrument<\/h4>\n\n\n\n<p>This has been quoted directly from GCC documentation:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><code>-finstrument-functions<\/code><\/p>\n\n\n\n<p>Generate instrumentation calls for entry and exit to functions. Just after function entry and just before function exit, the following profiling functions are called with the address of the current function and its call site. (On some platforms,&nbsp;<code>__builtin_return_address<\/code>&nbsp;does not work beyond the current function, so the call site information may not be available to the profiling functions otherwise.)<\/p>\n\n\n\n<p><code>void __cyg_profile_func_enter (void *this_fn, void *call_site);<\/code><br><code>void __cyg_profile_func_exit (void *this_fn, void *call_site);<\/code><\/p>\n\n\n\n<p>The first argument is the address of the start of the current function, which may be looked up exactly in the symbol table.<\/p>\n\n\n\n<p>This instrumentation is also done for functions expanded inline in other functions. The profiling calls indicate where, conceptually, the inline function is entered and exited. This means that addressable versions of such functions must be available. If all your uses of a function are expanded inline, this may mean an additional expansion of code size. If you use extern inline in your C code, an addressable version of such functions must be provided. (This is normally the case anyway, but if you get lucky and the optimizer always expands the functions inline, you might have gotten away without providing static copies.)<\/p>\n\n\n\n<p>A function may be given the attribute no_instrument_function, in which case this instrumentation is not done. This can be used, for example, for the profiling functions listed above, high-priority interrupt routines, and any functions from which the profiling functions cannot safely be called (perhaps signal handlers, if the profiling routines generate output or allocate memory).<\/p>\n<\/blockquote>\n\n\n\n<p>In practice, we can instrument each function of the target program. For each function call\/return, the respective&nbsp;<code>__cyg_profile_func_*<\/code>&nbsp;will be called passing the address of the function called and the call site\u2019s address. Let\u2019s have a try, let\u2019s write a&nbsp;<code>target.c<\/code>&nbsp;program.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Here you can find the raw files:&nbsp;<a href=\"https:\/\/gabrieleserra.ml\/assets\/postdata\/an-introduction-to-gcc-and-gccs-plugins\/instrument-1\/\">example-1<\/a><\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h>\n\n\/\/ Note:\n\/\/ We need 'no_instrument_function' attribute on __cyg_profile_fun_*\n\n\/\/ called every time a function get called\n__attribute__ ((no_instrument_function)) void __cyg_profile_func_enter (void *this_fn, void *call_site)\n{\n    printf(\"Entering in 0x%lx from 0x%lx...\\n\", (unsigned long)this_fn, (unsigned long)call_site);\n}\n\n\/\/ called every time a function returns\n__attribute__ ((no_instrument_function)) void __cyg_profile_func_exit  (void *this_fn, void *call_site)\n{\n    printf(\"Exiting from 0x%lx to 0x%lx...\\n\", (unsigned long)this_fn, (unsigned long)call_site);\n}\n\nvoid f1()\n{\n  return;\n}\n\nint main()\n{\n  printf(\"I'm a target C program.\\n\");\n  f1();\n  return 1;\n}<\/code><\/pre>\n\n\n\n<p>Ok, the program above is a foolish example. But it can be enough to understand what are the issues that may arise when using this approach. Actually, we have a&nbsp;<code>main<\/code>&nbsp;function that calls the function&nbsp;<code>f1<\/code>.<\/p>\n\n\n\n<p>And then we wrote the two&nbsp;<code>__cyg_profile_fun_*<\/code>&nbsp;that will be called each function call\/return. Of course, when&nbsp;<code>__cyg_profile_fun_*<\/code>&nbsp;are called, they trigger the mechanism again, so we need to protect them with&nbsp;<code>no_instrument_function<\/code>. Indeed, without the attribute, we can incur easily in a stack overflow.<\/p>\n\n\n\n<p>Let\u2019s compile and run, including, for convenience, debugging symbols.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>$<\/strong> gcc target.c -g -finstrument-functions -o bin\n<strong>$<\/strong> .\/bin\n<strong>Entering in 0x5561cfe341ef from 0x7f02c8f231e3... #<\/strong> enter in main\nI'm a target C program.\n<strong>Entering in 0x5561cfe341cf from 0x5561cfe34236... #<\/strong> enter in f1 from main\n<strong>Exiting from 0x5561cfe341cf to 0x5561cfe34236...  #<\/strong> exit from f1 to main\n<strong>Exiting from 0x5561cfe341ef to 0x7f02c8f231e3...  #<\/strong> exit from main<\/code><\/pre>\n\n\n\n<p>The profiling functions are placed after the prologue of the main and before the epilogue. Let\u2019s dump the program assembly to understand what happened<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>$<\/strong> objdump -d bin\n...\nDisassembly of section .text:\n...\n<strong>0000000000001206 &lt;main><\/strong>:\n...\n  ...\n  120a:       55                      push   %rbp\n  120b:       48 89 e5                mov    %rsp,%rbp\n  120e:       53                      push   %rbx\n<strong>  120f:       48 83 ec 08             sub    $<\/strong>0x8,%rsp\n  ...\n<strong>  1224:       e8 40 ff ff ff          callq  1169 &lt;__cyg_profile_func_enter><\/strong>\n  ...\n<strong>  1255:       e8 42 ff ff ff          callq  119c &lt;__cyg_profile_func_exit><\/strong>\n  ...\n  1261:       5d                      pop    %rbp\n  1262:       c3                      retq  \n  ...<\/code><\/pre>\n\n\n\n<p>This is what happens, at least on my workstation. It was easy to set up everything, writing two functions is enough, and we do not have to bother ourselves with plugins, GCC internals, strange compiling options, and stuff like that. But this is the only positive aspect, unfortunately!<\/p>\n\n\n\n<p>Indeed, in the example, we tracked the program flow only because it was an elementary target program. But imagine if you had thousands of lines of code and branches. Also, really it is missing a way to get information about the function we are analyzing. We have only an address, actually a virtual one! Let\u2019s dump the symbol table of our binary.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>$<\/strong> readelf -s bin\n...\nSymbol table '.symtab' contains 74 entries:\n...\n    ...\n    64: 00000000000011cf    49 FUNC    GLOBAL DEFAULT   16 f1\n    ...\n    69: 00000000000011ef    87 FUNC    GLOBAL DEFAULT   16 main\n    ...\n    73: 000000000000119c    51 FUNC    GLOBAL DEFAULT   16 __cyg_profile_func_exit<\/code><\/pre>\n\n\n\n<p>Symbols are stored in the binary, starting from 0x0. The address got on the screen are virtual. In many embedded systems, there is no virtual memory, and this approach could simply work. But in modern OSes, address spaces are randomized for a new process. When we try to get the line from the address (we can use the&nbsp;<code>addr2line<\/code>&nbsp;tool), we simply get a bunch of&nbsp;<code>??<\/code>. Because, as stated above, the addresses printed are virtual.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>$<\/strong> addr2line -f -e bin 0x5561cfe341ef # VA: it is not valid for addr2line\n??\n??:0\n<strong>$<\/strong> addr2line -f -e bin 0x11ef\nmain\ntarget.c:24<\/code><\/pre>\n\n\n\n<p>While the process is running, you can get the base address of the process in memory reading the memory map of the process<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>$<\/strong> cat \/proc\/&lt;pid>\/maps\n5561cfe33000-5561cfe34000 r--p 00000000 08:02 5378191                    ...\/bin\n5561cfe34000-5561cfe35000 r-xp 00001000 08:02 5378191                    ...\/bin\n5561cfe35000-5561cfe36000 r--p 00002000 08:02 5378191                    ...\/bin\n5561cfe36000-5561cfe37000 r--p 00002000 08:02 5378191                    ...\/bin\n5561cfe37000-5561cfe38000 rw-p 00003000 08:02 5378191                    ...\/bin\n5561d11b2000-5561d11d3000 rw-p 00000000 00:00 0                          &#91;heap]\n7ff032b87000-7ff032bac000 r--p 00000000 08:02 2902                       \/usr\/lib\/x86_64-linux-gnu\/libc-2.30.so\n7ff032bac000-7ff032d24000 r-xp 00025000 08:02 2902                       \/usr\/lib\/x86_64-linux-gnu\/libc-2.30.so\n7ff032d24000-7ff032d6e000 r--p 0019d000 08:02 2902                       \/usr\/lib\/x86_64-linux-gnu\/libc-2.30.so\n7ff032d6e000-7ff032d71000 r--p 001e6000 08:02 2902                       \/usr\/lib\/x86_64-linux-gnu\/libc-2.30.so\n7ff032d71000-7ff032d74000 rw-p 001e9000 08:02 2902                       \/usr\/lib\/x86_64-linux-gnu\/libc-2.30.so\n7ff032d74000-7ff032d7a000 rw-p 00000000 00:00 0 \n7ff032d93000-7ff032d94000 r--p 00000000 08:02 2894                       \/usr\/lib\/x86_64-linux-gnu\/ld-2.30.so\n7ff032d94000-7ff032db6000 r-xp 00001000 08:02 2894                       \/usr\/lib\/x86_64-linux-gnu\/ld-2.30.so\n7ff032db6000-7ff032dbe000 r--p 00023000 08:02 2894                       \/usr\/lib\/x86_64-linux-gnu\/ld-2.30.so\n7ff032dbf000-7ff032dc0000 r--p 0002b000 08:02 2894                       \/usr\/lib\/x86_64-linux-gnu\/ld-2.30.so\n7ff032dc0000-7ff032dc1000 rw-p 0002c000 08:02 2894                       \/usr\/lib\/x86_64-linux-gnu\/ld-2.30.so\n7ff032dc1000-7ff032dc2000 rw-p 00000000 00:00 0 \n7ffeaf8a5000-7ffeaf8c6000 rw-p 00000000 00:00 0                          &#91;stack]\n7ffeaf94d000-7ffeaf950000 r--p 00000000 00:00 0                          &#91;vvar]\n7ffeaf950000-7ffeaf951000 r-xp 00000000 00:00 0                          &#91;vdso]\nffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0                  &#91;vsyscall]<\/code><\/pre>\n\n\n\n<p>The memory map of the process is composed of many blocks. Here below, I\u2019ve reported a simplified version (obviously this is valid only for Linux!).<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/gabrieleserra.ml\/assets\/postdata\/an-introduction-to-gcc-and-gccs-plugins\/images\/memmap.png\" alt=\"Memory map of Linux process\"\/><\/figure>\n\n\n\n<p>Thanks to&nbsp;<a href=\"https:\/\/retis.sssup.it\/~a.biondi\/\">Alessandro Biondi<\/a>&nbsp;for the image.<\/p>\n\n\n\n<p>We need the program image base address, identifiable with the name of our binary. Then with a simple subtraction, we can prove everything works.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>0x5561cfe341ef - # main virtual address \n0x5561cfe33000 = # process base address\n0x0000000011ef   # main symbol location<\/code><\/pre>\n\n\n\n<p>Last note, in this example, the first thing that these functions do is call the other one but, keep attention, the call site is the address in which the function gets called and not the caller function address!<\/p>\n\n\n\n<p>In conclusion, this approach is straightforward to set up but has a lot of weaknesses.<\/p>\n\n\n\n<p><strong>PROS<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Simple to setup<\/li>\n<\/ul>\n\n\n\n<p><strong>CONS<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Not performance-oriented, you have two additional function calls for each function<\/li>\n\n\n\n<li>It is difficult to modify the profiling function\u2019s behavior concerning the function who received instrumentation.<\/li>\n\n\n\n<li>It is really complicated to interact with code and to get function names or info.<\/li>\n\n\n\n<li>The profiling functions must be present in the target program<\/li>\n\n\n\n<li>Function calls always inserted after the prologue and before the epilogue<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"312-gcc-option--fpatchable\">3.1.2.&nbsp;<a><\/a>GCC option: -fpatchable<\/h4>\n\n\n\n<p>This has been quoted, again, directly from GCC documentation<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><code>-fpatchable-function-entry=N[,M]<\/code><\/p>\n\n\n\n<p>Generate N NOPs right at the beginning of each function, with the function entry point before the Mth NOP. If M is omitted, it defaults to 0 so the function entry points to the address just at the first NOP. The NOP instructions reserve extra space which can be used to patch in any desired instrumentation at run time, provided that the code segment is writable. The amount of space is controllable indirectly via the number of NOPs; the NOP instruction used corresponds to the instruction emitted by the internal GCC back-end interface gen_nop. This behavior is target-specific and may also depend on the architecture variant and\/or other compilation options.<\/p>\n\n\n\n<p>For run-time identification, the starting addresses of these areas, which correspond to their respective function entries minus M, are additionally collected in the&nbsp;<code>__patchable_function_entries<\/code>&nbsp;section of the resulting binary.<\/p>\n\n\n\n<p>Note that the value of&nbsp;<code>__attribute__ ((patchable_function_entry (N,M)))<\/code>&nbsp;takes precedence over command-line option&nbsp;<code>-fpatchable-function-entry=N,M<\/code>. This can &gt;be used to increase the area size or to remove it completely on a single function. If N=0, no pad location is recorded.<\/p>\n\n\n\n<p>The NOP instructions are inserted at\u2014and maybe before, depending on M\u2014the function entry address, even before the prologue.<\/p>\n\n\n\n<p>The maximum value of N and M is 65535.<\/p>\n<\/blockquote>\n\n\n\n<p>This is a bit simpler than the previous one. The explanation is more accessible, it is useful to \u201cmake space\u201d before the function prologue to patch the function with some code. If we need to check the function behavior before the prologue, we can do it quickly.<\/p>\n\n\n\n<p>At our disposal, we have two parameters, N and M. N, which indicates the number of&nbsp;<code>NOPs<\/code>&nbsp;we want to insert before the function prologue while M indicates the displacement. Let\u2019s try it with a simple target C program.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Here you can find the raw files:&nbsp;<a href=\"https:\/\/gabrieleserra.ml\/assets\/postdata\/an-introduction-to-gcc-and-gccs-plugins\/instrument-2\/\">example-2<\/a><\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h>\n\nvoid f1()\n{\n    return;\n}\n\nint main()\n{\n  printf(\"I'm a target C program.\\n\");\n  f1();\n  return 1;\n}<\/code><\/pre>\n\n\n\n<p>We will compile in two manners, one with the patchable option and the other without.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>$<\/strong> gcc target.c -g -fpatchable-function-entry=10 -o bin_patchable\n<strong>$<\/strong> gcc target.c -g -o bin\n<strong>$<\/strong> objdump -d bin_patchable > dis_patchable\n<strong>$<\/strong> objdump -d bin > dis<\/code><\/pre>\n\n\n\n<p>Ok, so let\u2019s compare them. I will attach an image, hoping it would be more evident than a&nbsp;<code>diff<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/gabrieleserra.ml\/assets\/postdata\/an-introduction-to-gcc-and-gccs-plugins\/images\/comparison.png\" alt=\"Comparison\"\/><\/figure>\n\n\n\n<p>We can appreciate 10&nbsp;<code>NOPs<\/code>&nbsp;added at the beginning of each function, leading to \u201cpatchable\u201d code. Let\u2019s try again using the M parameter.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>$<\/strong> gcc target.c -g -fpatchable-function-entry=10,5 -o bin_patchable\n<strong>$<\/strong> gcc target.c -g -o bin<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/gabrieleserra.ml\/assets\/postdata\/an-introduction-to-gcc-and-gccs-plugins\/images\/comparison_shifted.png\" alt=\"Comparison\"\/><\/figure>\n\n\n\n<p>Also, 10&nbsp;<code>NOPs<\/code>&nbsp;were added but shifted up by 5, then modifying the functions placed before. Although the mechanism is simple, personally, I think it leaves a poor control of what happens actually.<\/p>\n\n\n\n<p><strong>PROS<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Simple to setup<\/li>\n\n\n\n<li>Good flexibility, you are free to place a variable number of NOPs and shift them<\/li>\n\n\n\n<li>Performance-oriented cause you can patch assembly directly<\/li>\n<\/ul>\n\n\n\n<p><strong>CONS<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Need a tool to patch the binary<\/li>\n\n\n\n<li>NOPs are added only at the beginning of the function<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"32-get-your-hands-dirty-working-with-gcc-internals\">3.2.&nbsp;<a><\/a>Get your hands dirty: working with GCC internals<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"321-overview-on-gcc-compilation-process\">3.2.1.&nbsp;<a><\/a>Overview on GCC compilation process<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Part of this section was built using material that I have found during my research on GCC internals and I want to say thanks to original authors and give them credits.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><em>Sangwan Kwon<\/em>\u00a0&#8211; An Overview of GCC\u00a0<a href=\"http:\/\/bitboom.github.io\/an-overview-of-gcc\">[8]<\/a><\/li>\n\n\n\n<li><em>Pop S\u00e9bastian<\/em>\u00a0&#8211; AST representation in GCC\u00a0<a href=\"http:\/\/icps.u-strasbg.fr\/~pop\/gcc-ast.html\">[9]<\/a><\/li>\n\n\n\n<li><em>Jens Vankeirsbilck<\/em>\u00a0&#8211; CFED GCC Plugin\u00a0<a href=\"https:\/\/github.com\/MGroupKULeuvenBrugesCampus\/CFED_Plugin\">[10]<\/a><\/li>\n\n\n\n<li><em>Uday Khedker<\/em>\u00a0&#8211; Introduction to RTL\u00a0<a href=\"https:\/\/www.cse.iitb.ac.in\/~uday\/courses\/cs715-09\/gcc-rtl.pdf\">[11]<\/a><\/li>\n<\/ul>\n<\/blockquote>\n\n\n\n<p>For sure, we have discovered that GCC\u2019s options are powerful but, at the same time, not enough if we need flexibility and performance. We need to understand something about GCC internals to exploit the power of GCC plugins. We will start from the basis.<\/p>\n\n\n\n<p>GCC (and, I think, almost all compilers) works analyzing code in subsequent phases called passes. At each pass, the compiler does some action, such as abstracting the representation of a program, optimizing data structures, etc. GCC organizes its compilation phase in several passes<a href=\"https:\/\/gcc.gnu.org\/onlinedocs\/gccint\/Passes.html\">[12]<\/a><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Parsing pass<\/strong>: The language front end turns text into bits.<\/li>\n\n\n\n<li><strong>Gimplification pass<\/strong>: The bits are turned into something we can optimize.<\/li>\n\n\n\n<li><strong>IPA passes<\/strong>: Inter-procedural optimizations.<\/li>\n\n\n\n<li><strong>Tree SSA passes<\/strong>: Optimizations on a high-level representation.<\/li>\n\n\n\n<li><strong>RTL passes<\/strong>: Optimizations on a low-level representation.<\/li>\n<\/ul>\n\n\n\n<p>I am all but an expert in this field, so if you want to dive deeper into the argument, refer to the GCC documentation. For our purposes, it is enough to check only some aspects.<\/p>\n\n\n\n<p>Talking simpler, we can say that all compilers include three macro-components: a front-end, a middle-end, and a back-end. The front-end macro-component considers all the things about the target program\u2019s language while the back-end deals with the target architecture.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/gabrieleserra.ml\/blog\/images\/gcc.jpg\" alt=\"GCC Passes\"\/><\/figure>\n\n\n\n<p>In practice, GCC analyzes the target program\u2019s code, visualizing it as an abstract tree, and then it builds a representation using GENERIC\/GIMPLE. Then, it examines the GIMPLE abstraction trying to operate some optimizations such as inlining functions. Then it performs the RTL pass where it works on the low-level representation of the program (RTL stands for register transfer layout). RTL is the way GCC uses to map GIMPLE code to the register of the machine.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/gabrieleserra.ml\/assets\/postdata\/an-introduction-to-gcc-and-gccs-plugins\/images\/gcc-com-proc.png\" alt=\"GCC Compilation process\"\/><\/figure>\n\n\n\n<p>As a consequence, with our plugin, we can operate mainly in two way:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>before or after the GIMPLE pass if we want to interact with the abstract representation letting GCC generate the low-level code<\/li>\n\n\n\n<li>at the RTL pass if we are worried about performance or we need to operate on the low-level representation<\/li>\n<\/ul>\n\n\n\n<p>Basically, we will see both approaches, trying to get the best of both.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"322-working-on-ast--genericgimple\">3.2.2.&nbsp;<a><\/a>Working on: AST &amp; GENERIC\/GIMPLE<\/h4>\n\n\n\n<p>AST (Abstract Syntax Trees) are intermediate representations produced by the GCC front-end. The purpose of GENERIC is to provide a language-independent way of representing an entire function as a tree. Actually,&nbsp;<code>tree<\/code>&nbsp;is the central data structure used by GCC in its internal representation of a target program. The&nbsp;<code>tree<\/code>, obviously, is composed of children nodes of type&nbsp;<code>tree<\/code>. Basically, a&nbsp;<code>tree<\/code>&nbsp;is a C pointer type that points to different varieties\u2019 object.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/gabrieleserra.ml\/assets\/postdata\/an-introduction-to-gcc-and-gccs-plugins\/images\/ast-generic-representation.png\" alt=\"AST\"\/><\/figure>\n\n\n\n<p>The image above shows what means represent a function with a&nbsp;<code>tree<\/code>. Each ellipse represents a node of the tree, described using GENERIC. Let\u2019s suppose we want to focus on the tree structure of a function.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/gabrieleserra.ml\/assets\/postdata\/an-introduction-to-gcc-and-gccs-plugins\/images\/function-decl.png\" alt=\"Function declaration\"\/><\/figure>\n\n\n\n<p>Here I have reported some examples taken from the sources I have linked above. The first is the declaration of a function.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/gabrieleserra.ml\/assets\/postdata\/an-introduction-to-gcc-and-gccs-plugins\/images\/compound-stmt.png\" alt=\"Compound statement\"\/><\/figure>\n\n\n\n<p>The body is a tree too composed, again, of tree nodes.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/gabrieleserra.ml\/assets\/postdata\/an-introduction-to-gcc-and-gccs-plugins\/images\/plus-expr.png\" alt=\"Expression\"\/><\/figure>\n\n\n\n<p>The last example refers to an expression.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>These images are taken from an article written in 2002. Take these images more as examples than reference because many things have been changed over the years.<\/p>\n<\/blockquote>\n\n\n\n<p>And then what is GIMPLE?<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>GIMPLE is a three-address representation derived from GENERIC by breaking down GENERIC expressions into tuples of no more than 3 operands<a href=\"https:\/\/gcc.gnu.org\/onlinedocs\/gccint\/GIMPLE.html\">[7]<\/a><\/p>\n<\/blockquote>\n\n\n\n<p>I won\u2019t say a lot more, let\u2019s try to implement something. For this example, the idea is simple: I want to register a&nbsp;<code>profiled<\/code>&nbsp;attribute. When the attribute is attached to a function, the function will be profiled, calling an&nbsp;<code>__inst_profile<\/code>&nbsp;function.<\/p>\n\n\n\n<p>Here we can see much useful stuff that can be reused to implement really complex compilation behavior.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Here you can find the raw files:&nbsp;<a href=\"https:\/\/gabrieleserra.ml\/assets\/postdata\/an-introduction-to-gcc-and-gccs-plugins\/instrument-3\/\">example-3<\/a><\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;gcc-plugin.h>\n#include &lt;tree.h>\n#include &lt;gimple.h>\n#include &lt;tree-pass.h>\n#include &lt;gimple-iterator.h>\n#include &lt;stringpool.h>\n#include &lt;attribs.h>\n\n\/**\n * When 1 enables verbose printing\n *\/\n#define DEBUG               1\n\n\/**\n * Name of the function called to profile code\n *\/\n#define FUNCTION_NAME       \"__inst_profile\"\n\n\/**\n * Name of the attribute used to instrument a function\n *\/\n#define ATTRIBUTE_NAME      \"profiled\"\n\n\/**\n * Name of this plugin\n *\/\n#define PLUGIN_NAME         \"inst_plugin\"\n\n\/**\n * Version of this plugin\n *\/\n#define PLUGIN_VERSION      \"0.1\"\n\n\/**\n * Help\/usage string for the plugin\n *\/\n#define PLUGIN_HELP         \"Usage: registers an attribute \" ATTRIBUTE_NAME\n\n\/**\n * Required GCC version\n *\/\n#define PLUGIN_GCC_BASEV    \"9.2.1\"\n\n\/\/ -----------------------------------------------------------------------------\n\/\/ GCC PLUGIN SETUP (BASIC INFO \/ LICENSE \/ REQUIRED VERSION)\n\/\/ -----------------------------------------------------------------------------\n\nint plugin_is_GPL_compatible;\n\n\/**\n * Additional information about the plugin. Used by --help and --version\n *\/\nstatic struct plugin_info inst_plugin_info =\n{\n  .version  = PLUGIN_VERSION,\n  .help     = PLUGIN_HELP,\n};\n\n\/**\n * Represents the gcc version we need. Used to void using an incompatible plugin \n *\/\nstatic struct plugin_gcc_version inst_plugin_ver =\n{\n  .basever  = PLUGIN_GCC_BASEV,\n};\n\n\/\/ -----------------------------------------------------------------------------\n\/\/ GCC EXTERNAL DECLARATION\n\/\/ -----------------------------------------------------------------------------\n\n\/**\n * Takes a tree node and returns the identifier string\n * @see https:\/\/gcc.gnu.org\/onlinedocs\/gccint\/Identifiers.html\n *\/\n#define FN_NAME(tree_fun) IDENTIFIER_POINTER (DECL_NAME (tree_fun))\n\n\/**\n * Takes a tree node and returns the identifier string length\n * @see https:\/\/gcc.gnu.org\/onlinedocs\/gccint\/Identifiers.html\n *\/\n#define FN_NAME_LEN(tree_fun) IDENTIFIER_LENGTH (DECL_NAME (tree_fun))\n\n\/**\n * Print GIMPLE statement G to FILE using SPC indentation spaces and FLAGS\n * @note Makes use of pp_gimple_stmt_1\n * @see Declared in gimple-pretty-print.h\n * @see Flags are listed in dumpfile.h\n *\/\nextern void print_gimple_stmt(FILE * file, gimple* g, int spc, dump_flags_t flags);\n\n\/**\n * Print tree T, and its successors, on file FILE. FLAGS specifies details to \n * show in the dump\n * @note Makes use of dump_generic_node\n * @see Declared in tree-pretty-print.h\n * @see Flags are listed in dumpfile.h\n *\/\nextern void print_generic_stmt(FILE* file, tree t, dump_flags_t flags);\n\n\/** \n * The global singleton context aka \"g\". The name is chosen to be easy to type\n * in a debugger. Represents the 'global state' of GCC\n * \n * GCC's internal state can be divided into zero or more \"parallel universe\" of \n * state; an instance of the class context is one such context of state\n * \n * @see Declared in context.h\n *\/\nextern gcc::context *g;\n\n\/\/ -----------------------------------------------------------------------------\n\/\/ GCC ATTRIBUTES MANAGEMENT (REGISTERING \/ CALLBACKS)\n\/\/ -----------------------------------------------------------------------------\n\n\/**\n * Insert a single ATTR into the attribute table\n * @see Declared in plugin.h\n * @note Insert the attribute into the 'gnu' attributes namespace\n *\/\nextern void register_attribute(const struct attribute_spec *attr);\n\n\/**\n * Attribute handler callback \n * @note NODE points to the node to which the attribute is to be applied. NAME \n * is the name of the attribute. ARGS is the TREE_LIST of arguments (may be \n * NULL). FLAGS gives information about the context of the attribute. \n * Afterwards, the attributes will be added unless *NO_ADD_ATTRS is set to true \n * (which should be done on error). Depending on FLAGS, any attributes to be \n * applied to another type or DECL later may be returned; otherwise the return \n * value should be NULL_TREE. This pointer may be NULL if no special handling is\n * required\n * @see Declared in tree-core.h\n *\/\nstatic tree handle_instrument_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs)\n{\n    #if DEBUG == 1\n        fprintf(stderr, \"> Found attribute\\n\");\n\n        fprintf(stderr, \"\\tnode = \");\n        print_generic_stmt(stderr, *node, TDF_NONE);\n        \n        fprintf(stderr, \"\\tname = \");\n        print_generic_stmt(stderr, name, TDF_NONE);\n    #endif\n\n    return NULL_TREE;\n}\n\n\/**\n * Structure describing an attribute and a function to handle it\n * @see Declared in tree-core.h\n * @note Refer to tree-core for docs about\n *\/\nstatic struct attribute_spec instrument_attr = {\n    ATTRIBUTE_NAME,                 \/* name *\/\n    0,                              \/* min_len *\/\n    0,                              \/* max_len *\/\n    false,                          \/* decl_req *\/\n    false,                          \/* type_req *\/\n    false,                           \/* fn_type_req *\/\n    false,                          \/* affects_type_identity *\/\n    handle_instrument_attribute,    \/* handler *\/\n    NULL                            \/* exclusions *\/\n};\n\n\/**\n * Plugin callback called during attribute registration \n *\/\nstatic void register_attributes(void *event_data, void *data)\n{\n    fprintf(stderr, \"> Registering attribute '%s'\\n\", ATTRIBUTE_NAME);\n    register_attribute(&amp;instrument_attr);\n}\n\n\/\/ -----------------------------------------------------------------------------\n\/\/ PLUGIN INSTRUMENTATION LOGICS\n\/\/ -----------------------------------------------------------------------------\n\n\/**\n * Create a function call to '__profile' and insert it before the given stmt\n *\/\nstatic void insert_instrumentation_fn(gimple* curr_stmt)\n{\n    \/\/ build function prototype\n    tree proto = build_function_type_list(\n            void_type_node,             \/\/ return type\n            NULL_TREE                   \/\/ varargs terminator\n        );           \n    \n    \/\/ builds and returns function declaration with NAME and PROTOTYPE\n    tree decl = build_fn_decl(FUNCTION_NAME, proto);\n\n    \/\/ build the GIMPLE function call to decl\n    gcall* call = gimple_build_call(decl, 0);\n\n    \/\/ get an iterator pointing to first basic block of the statement\n    gimple_stmt_iterator gsi = gsi_for_stmt(curr_stmt);\n\n    \/\/ insert it before the statement that was passed as the first argument\n    gsi_insert_before(&amp;gsi, call, GSI_NEW_STMT);\n}\n\n\/**\n * For each function lookup attributes and attach profiling function\n *\/\nstatic unsigned int instrument_assignments_plugin_exec(void)\n{\n    \/\/ get the FUNCTION_DECL of the function whose body we are reading\n    tree fndef = current_function_decl;\n    \n    \/\/ print the function name\n    fprintf(stderr, \"> Inspecting function '%s'\\n\", FN_NAME(fndef));\n\n    \/\/ get the attributes list\n    tree attrlist = DECL_ATTRIBUTES(fndef);\n\n    \/\/ lookup into attribute list searcing for our registered attribute\n    tree attr = lookup_attribute(ATTRIBUTE_NAME, attrlist);\n\n    \/\/ if the attribute is not present\n    if (attr == NULL_TREE)\n        return 0;\n\n    \/\/ attribute was in the list\n    fprintf(stderr, \"\\t attribute %s found! \\n\", ATTRIBUTE_NAME);\n\n    \/\/ get function entry block\n    basic_block entry = ENTRY_BLOCK_PTR_FOR_FN(cfun)->next_bb;\n\n    \/\/ get the first statement\n    gimple* first_stmt = gsi_stmt(gsi_start_bb(entry));\n\n    \/\/ warn the user we are adding a profiling function\n    fprintf(stderr, \"\\t adding function call before \");\n    print_gimple_stmt(stderr, first_stmt, 0, TDF_NONE);\n\n    \/\/ insert the function\n    insert_instrumentation_fn(first_stmt);\n\n    \/\/ done!\n    return 0;\n}\n\n\/** \n * Metadata for a pass, non-varying across all instances of a pass\n * @see Declared in tree-pass.h\n * @note Refer to tree-pass for docs about\n *\/\nstruct pass_data ins_pass_data =\n{\n    .type = GIMPLE_PASS,                                    \/\/ type of pass\n    .name = PLUGIN_NAME,                                    \/\/ name of plugin\n    .optinfo_flags = OPTGROUP_NONE,                         \/\/ no opt dump\n    .tv_id = TV_NONE,                                       \/\/ no timevar (see timevar.h)\n    .properties_required = PROP_gimple_any,                 \/\/ entire gimple grammar as input\n    .properties_provided = 0,                               \/\/ no prop in output\n    .properties_destroyed = 0,                              \/\/ no prop removed\n    .todo_flags_start = 0,                                  \/\/ need nothing before\n    .todo_flags_finish = TODO_update_ssa|TODO_cleanup_cfg   \/\/ need to update SSA repr after and repair cfg\n};\n\n\/**\n * Definition of our instrumentation GIMPLE pass\n * @note Extends gimple_opt_pass class\n * @see Declared in tree-pass.h\n *\/\nclass ins_gimple_pass : public gimple_opt_pass\n{\npublic:\n\n    \/**\n     * Constructor\n     *\/\n    ins_gimple_pass (const pass_data&amp; data, gcc::context *ctxt) : gimple_opt_pass (data, ctxt) {}\n\n    \/**\n     * This and all sub-passes are executed only if the function returns true\n     * @note Defined in opt_pass father class\n     * @see Defined in tree-pass.h\n     *\/ \n    bool gate (function* gate_fun) \n    {\n        return true;\n    }\n\n    \/**\n     * This is the code to run when pass is executed\n     * @note Defined in opt_pass father class\n     * @see Defined in tree-pass.h\n     *\/\n    unsigned int execute(function* exec_fun)\n    {\n        return instrument_assignments_plugin_exec();\n    }\n};\n\n\/\/ instanciate a new instrumentation GIMPLE pass\nins_gimple_pass inst_pass = ins_gimple_pass(ins_pass_data, g);\n\n\/\/ -----------------------------------------------------------------------------\n\/\/ PLUGIN INITIALIZATION\n\/\/ -----------------------------------------------------------------------------\n\n\/**\n * Initializes the plugin. Returns 0 if initialization finishes successfully. \n *\/\nint plugin_init(struct plugin_name_args *info, struct plugin_gcc_version *ver)\n{\n    \/\/ new pass that will be registered\n    struct register_pass_info pass;\n\n    \/\/ this plugin is compatible only with specified base ver\n    if (strncmp(inst_plugin_ver.basever, ver->basever, strlen(ver->basever)))\n        return 1;\n\n    \/\/ tell to GCC some info about this plugin\n    register_callback(PLUGIN_NAME, PLUGIN_INFO, NULL, &amp;inst_plugin_info);\n\n    \/\/ warn the user about the presence of this plugin\n    printf(\"> Instrumentation plugin '%s @ %s' was loaded onto GCC\\n\", PLUGIN_NAME, PLUGIN_VERSION);\n\n    \/\/ insert inst pass into the struct used to register the pass\n    pass.pass = &amp;inst_pass;\n\n    \/\/ and get called after GCC has produced SSA representation  \n    pass.reference_pass_name = \"ssa\";\n\n    \/\/ after the first opt pass to be sure opt will not throw away our stuff\n    pass.ref_pass_instance_number = 1;\n    pass.pos_op = PASS_POS_INSERT_AFTER;\n\n    \/\/ add our pass hooking into pass manager\n    register_callback(PLUGIN_NAME, PLUGIN_PASS_MANAGER_SETUP, NULL, &amp;pass);\n\n    \/\/ get called at attribute registration\n    register_callback(PLUGIN_NAME, PLUGIN_ATTRIBUTES, register_attributes, NULL);\n\n    \/\/ everthing has worked\n    return 0;\n}<\/code><\/pre>\n\n\n\n<p>The code is fully commented. Unfortunately, it is tough to explain everything step by step.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h>\n\nvoid __inst_profile()\n{\n    printf(\"Do something here!\\n\");\n}\n\n__attribute((profiled)) void f1()\n{\n    int a;\n    a = a + 1;\n    return;\n}\n\nint main()\n{\n    printf(\"I'm a target C program.\\n\");\n    f1();\n    return 1;\n}<\/code><\/pre>\n\n\n\n<p>So let\u2019s write a simple target program and proceed to compilation!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>$<\/strong> gcc target.c -fplugin=`pwd`\/inst_plugin.so -o bin\n<strong>><\/strong> Instrumentation plugin 'inst_plugin @ 0.1' was loaded onto GCC\n<strong>><\/strong> Registering attribute 'profiled'\n<strong>><\/strong> Found attribute\n        node = f1\n        name = profiled\n<strong>><\/strong> Inspecting function '__inst_profile'\n<strong>><\/strong> Inspecting function 'f1'\n         attribute profiled found! \n<strong>         adding function call before a_2 = a_1(D) + 1;<\/strong>\n<strong>><\/strong> Inspecting function 'main'\n\n<strong>$<\/strong> .\/bin\nI'm a target C program.\nDo something here!<\/code><\/pre>\n\n\n\n<p>Fine! The plugin was loaded onto GCC, and then, when inspecting functions, it found the attribute. At that point, it inserted the function call. When we run the binary, we can appreciate the output is enriched with the function call!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"33-instrument-code-with-low-level-asm\">3.3.&nbsp;<a><\/a>Instrument code with low-level ASM<\/h3>\n\n\n\n<p>In this last section, we want to examine the question more in-depth. The idea is to get our hands dirty and work directly at the low-level. Why we have to do this? Actually, it depends, maybe you want to realize something more powerful or with better performance. Or you need to output specific instructions for some reason. In this example, we will try to implement the same stuff of the other sections but avoiding the function call mechanism.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"331-introduction-to-rtl-language\">3.3.1.&nbsp;<a><\/a>Introduction to RTL language<\/h4>\n\n\n\n<p>This last section deals with low-level representation created by GCC and represented with RTL (Register Transfer Language). RTL is, as the name suggests, a language in which the instructions are built in a kind of algebraic form that describes what the instructions really do. Each RTL instruction represents, pretty much, the instruction that will be outputted by GCC as assembly opcodes.<\/p>\n\n\n\n<p>RTL uses five kinds of objects<a href=\"https:\/\/gcc.gnu.org\/onlinedocs\/gccint\/RTL-Objects.html#RTL-Objects\">[13]<\/a>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>expressions<\/li>\n\n\n\n<li>integers<\/li>\n\n\n\n<li>wide integers<\/li>\n\n\n\n<li>strings<\/li>\n\n\n\n<li>vectors<\/li>\n<\/ul>\n\n\n\n<p>Each RTL object is, practically, a list made up of structures that point at other structures. We focus on expressions, that are the most important ones. Like the other objects, an RTL expression or&nbsp;<code>rtx<\/code>&nbsp;is a structure, referred with a pointer.<\/p>\n\n\n\n<p>Expressions are classified by expression codes (also called RTX codes). The expression code is a name defined in rtl.def. The possible expression codes and their meanings are machine-independent. The RTX code can be extracted with the macro&nbsp;<code>GET_CODE (x)<\/code>&nbsp;and altered with&nbsp;<code>PUT_CODE (x, newcode)<\/code>.<\/p>\n\n\n\n<p>Let\u2019s analyze one of the instructions that compose the prologue of a function&nbsp;<code>push %ebp<\/code>. This instruction is represented in RTL by the following RTL expression.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(insn\/f 13 22 14            \/\/ \/f means that it is part of a function prologue\n                            \/\/ isns number 13, followed by isns 14 and preceded by 22   \n  (set                      \/\/ represent the action of storing a value somewhere\n    (mem:DI                 \/\/ represents a reference to main memory (double integer 8 byte)\n      (pre_dec:DI           \/\/ before accessing needed to decrement the stack pointer\n        (reg\/f:DI 7 sp)     \/\/ reference to the 7th register, sp (8 byte) that contains a pointer\n      ) &#91;0  S8 A8]          \/\/ no alias set, access to 8 bytes memory, 8 byte aligned expression\n    )\n    (reg\/f:DI 6 bp)         \/\/ access to the 6th reg. bp, that contains a pointer\n  ) \"target.c\":11:1 -1      \/\/ found that in target.c line 11\n  (nil)                     \/\/ end of list of rtx\n)<\/code><\/pre>\n\n\n\n<p>RTL is a language that provides a lot of information! It starts saying the instruction&nbsp;<code>13<\/code>&nbsp;will be followed by instruction&nbsp;<code>14<\/code>&nbsp;and preceded by instruction&nbsp;<code>22<\/code>. Then it says that the instruction takes apart in a function prologue with the flag&nbsp;<code>\/f<\/code>.<\/p>\n\n\n\n<p>Subsequently, it says the instruction will store a value in the main memory. The value to be stored must be taken from the 6th register of the machine, the&nbsp;<code>bp<\/code>&nbsp;register taking the entire 8-byte value, and also indicates that the register contains a&nbsp;<code>frame_related<\/code>&nbsp;pointer (flag&nbsp;<code>\/f<\/code>). The place in which storing is calculated using the 7th register of the machine&nbsp;<code>sp<\/code>&nbsp;using all 8 bytes and indicates that&nbsp;<code>sp<\/code>&nbsp;contains a&nbsp;<code>frame_related<\/code>&nbsp;pointer (flag&nbsp;<code>\/f<\/code>). Furthermore, the access to the memory must be preceded by a decrement of the register itself.<\/p>\n\n\n\n<p>For each operation we need to do at a low-level, we have to take care of RTL. GCC has its own API to build RTX expression. Each RTX expression must have a side one, namely the modification of the state of the machine. The most common are<a href=\"https:\/\/gcc.gnu.org\/onlinedocs\/gccint\/Side-Effects.html#Side-Effects\">[14]<\/a>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>set lval x<\/code>: The action of storing the value of\u00a0<code>x<\/code>\u00a0into the place represented by\u00a0<code>lval<\/code><\/li>\n\n\n\n<li><code>return<\/code>: Return from the current function<\/li>\n\n\n\n<li><code>call function nargs<\/code>: Function call where\u00a0<code>function<\/code>\u00a0is a mem expression whose address is the address of the function to be called<\/li>\n\n\n\n<li><code>clobber x<\/code>: The possible storing of value into\u00a0<code>x<\/code>, which must be a reg, scratch, parallel or mem expression<\/li>\n\n\n\n<li><code>use x<\/code>: The use of the value of\u00a0<code>x<\/code>. It indicates that the value in\u00a0<code>x<\/code>\u00a0at this point in the program is needed<\/li>\n\n\n\n<li><code>parallel [x0 x1 \u2026]<\/code>: Several side effects performed in parallel<\/li>\n\n\n\n<li><code>cond_exec [cond expr]<\/code>: Conditionally executed expression. The\u00a0<code>expr<\/code>\u00a0is executed only if the\u00a0<code>cond<\/code>\u00a0is nonzero<\/li>\n\n\n\n<li><code>asm_input s<\/code>: Literal assembler code as described by the string\u00a0<code>s<\/code><\/li>\n<\/ul>\n\n\n\n<p>The&nbsp;<code>push<\/code>&nbsp;instruction we have seen so far has the side effect of storing the value in the memory. In practice, when we want to modify the target program\u2019s behavior with our plugin, we need to build RT expression and then make the plugin emit the RTX in the chosen locus.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"332-build-something-with-rtl\">3.3.2.&nbsp;<a><\/a>Build something with RTL<\/h4>\n\n\n\n<p>Let\u2019s imagine we want to build an instruction to add something to a register, such as a simple&nbsp;<code>addq $immediate, %rax<\/code>. We have to develop the expression using GCC API.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/* Most used reg number:\n  AX_REG    0\n  DX_REG    1\n  CX_REG    2\n  BX_REG    3\n  SI_REG    4\n  DI_REG    5\n  BP_REG    6\n  SP_REG    7\n  FLAGS_REG 17\n*\/\n\/* Most used machine modes:\n  VOIDmode: absence of a mode\n  BImode:   bit\n  QImode:   quarter-integer (a single byte)\n  HImode:   half-integer (two-byte integer)\n  SImode:   single-integer (four-byte integer)\n  DImode:   double-integer (eight-byte integer)\n  CCmode:   condition-code (result of a comparison operation)\n  BLKmode:  block (string or vector mem reference)\n*\/\n\nrtx reg = gen_rtx_REG(DImode, 0);         \/\/ access to ax in 64 bit mode (rax)\nrtx imm = gen_rtx_CONST_INT(DImode, 5);   \/\/ immediate int64 $5\nrtx add = gen_rtx_PLUS(DImode, reg, imm); \/\/ addq instruction with reg and imm operand \nrtx set = gen_rtx_SET(reg, add);          \/\/ save the result of instr. to reg\n\nprint_rtl_single(stderr, set);\n\n\/* output:\n(set (reg:DI 0 ax)\n    (plus:DI (reg:DI 0 ax)\n        (const_int 5 &#91;0x5])))\n*\/<\/code><\/pre>\n\n\n\n<p>Tremendous fatigue! Also, if you want to be precise, the ADD instruction could modify the FLAG register in case of overflow, for instance! Then the&nbsp;<code>rtx<\/code>&nbsp;must be expanded further! We need to use the&nbsp;<code>clobber<\/code>&nbsp;side effect!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rtx reg = gen_rtx_REG(DImode, 0);         \/\/ access to ax in 64 bit mode (rax)\nrtx imm = gen_rtx_CONST_INT(DImode, 5);   \/\/ immediate int64 $5\nrtx add = gen_rtx_PLUS(DImode, reg, imm); \/\/ addq instruction with reg and imm operand \nrtx set = gen_rtx_SET(reg, add);          \/\/ save the result of instr. to reg\nrtx flg = gen_rtx_REG(CCmode, FLAGS_REG); \/\/ access to conditions in flags reg \nrtx clo = gen_rtx_CLOBBER(VOIDmode, flg); \/\/ possible modification of reg flags\n\nrtvec vec = rtvec_alloc(2);\nvec->elem&#91;0] = set;\nvec->elem&#91;1] = clo;\n\nrtx par = gen_rtx_PARALLEL(VOIDmode, vec);\nprint_rtl_single(stderr, par);\n\n\/* output\n(parallel &#91;\n  (set (reg:DI 0 ax)\n      (plus:DI (reg:DI 0 ax)\n          (const_int 5 &#91;0x5])))\n  (clobber (reg:CC 17 flags))\n])\n*\/<\/code><\/pre>\n\n\n\n<p>Sometimes build an RTX is complicated and involves a lot of side effects and stuff. My hint is to read the RTL produced by GCC during the compilation of a program and then get the inspiration to build each and every RTX you need using the compilation\u2019s option&nbsp;<code>-fdump-rtl-expand<\/code>&nbsp;.<\/p>\n\n\n\n<p>So we realize that do something with RTL is not so easy. However,&nbsp;<code>asm_input<\/code>&nbsp;comes to save us. Indeed one of the possible side effects is the direct output of ASM instructions. In theory, they thought, if someone places ASM inline, he knows what is doing, so we can directly output the ASM code.<\/p>\n\n\n\n<p>The only thing to take care is to declare it as volatile (otherwise could be stripped off during optimization) and then remember to declare where the ASM code will overwrite stuff in memory. Seems like we had to build, again, a complex RTX expression. However, here GCC comes in help also. We can declare all memory locations as clobber (just be sure!) using the BLK mode and the&nbsp;<code>scratch<\/code>&nbsp;RTX!<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>If x is (mem:BLK (const_int 0)) or (mem:BLK (scratch)), it means that all memory locations must be presumed clobbered.&nbsp;<a href=\"https:\/\/gcc.gnu.org\/onlinedocs\/gccint\/Side-Effects.html#Side-Effects\">[14]<\/a><\/p>\n<\/blockquote>\n\n\n\n<p>Of course, here, GCC will be unable to perform optimization or reordering of instruction, but clearly, if you specify ASM code, 99% you want to compiler to output that exact code!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>char opcodes&#91;] = \"#do something in asm...\";\n\nrtx cod = gen_rtx_ASM_INPUT(VOIDmode, opcodes);\nMEM_VOLATILE_P (cod) = 1; \/\/ set as volatile\nrtx mem = gen_rtx_MEM(BLKmode, gen_rtx_SCRATCH(VOIDmode)); \/\/ all memory locations!\nrtx clo = gen_rtx_CLOBBER(VOIDmode, mem); \/\/ all memory locations could be written\nrtx flg = gen_rtx_REG(CCmode, FLAGS_REG); \/\/ access to conditions in flags reg \nrtx clf = gen_rtx_CLOBBER(VOIDmode, flg); \/\/ possible modification of reg flags\n\nrtvec vec = rtvec_alloc(3);\nvec->elem&#91;0] = cod;\nvec->elem&#91;1] = clo;\nvec->elem&#91;2] = clf;\nrtx par = gen_rtx_PARALLEL(VOIDmode, vec);\n\nprint_rtl_single(stderr, par);\n\n\/* output\n(parallel &#91;\n        (asm_input\/v (\"#do something in asm...\"))\n        (clobber (mem:BLK (scratch) &#91;0  A8]))\n        (clobber (reg:CC 17 flags))\n    ])\n*\/<\/code><\/pre>\n\n\n\n<p>Here we are! In this way, we can output the code we want without building any RTL expression! Also, we can mix both approaches.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"333-instrument-functions-using-rtl\">3.3.3.&nbsp;<a><\/a>Instrument functions using RTL<\/h4>\n\n\n\n<p>In this last example, we want to instrument a target program, similar to the previous models. However, here we will push on efficiency, instrumenting each function with a piece of code that does not contain prologue nor epilogue. Basically, we want to instrument each function with a piece of code and not a \u201creal\u201d function!<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Here you can find the raw files:&nbsp;<a href=\"https:\/\/gabrieleserra.ml\/assets\/postdata\/an-introduction-to-gcc-and-gccs-plugins\/instrument-4\/\">example-4<\/a><\/p>\n<\/blockquote>\n\n\n\n<p>Let\u2019s check the target program.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ attribute naked force GCC to strip off prologue and epilogue\n\/\/ then we need to implement our \"fake epilogue\"\n\/\/ in this simple example as a JMP back to the address passed as arg\n__attribute((naked)) void __inst_profile(long retaddr)\n{\n    printf(\"Do something here!\\n\");\n    asm(\"jmp *%0\" :: \"r\" (retaddr));\n}\n\n\/\/ attribute profiled will trigger the instrumentation!\n__attribute((profiled)) void f1()\n{\n    int a = 5;\n    a = a + 5;  \n    return;\n}\n\nint main()\n{\n    printf(\"I'm a target C program.\\n\");\n    f1();\n    return 1;\n}<\/code><\/pre>\n\n\n\n<p>We want that our plugin add the code to realize the following: during&nbsp;<code>f1<\/code>&nbsp;(before its prologue) will jump to the function, print \u201cDo something here\u201d and then return back to&nbsp;<code>f1<\/code>.<\/p>\n\n\n\n<p>In practice, we need to output the following ASM code before&nbsp;<code>f1<\/code>&nbsp;prologue.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>push  %rdi              # push function 1st argument to avoid dirty it\nlea   0x2(%rip), %rdi   # load instr pointer with displacement and save in rdi\njmp   FUNCTION_NAME     # jump to profiling function\npop   %rdi              # pop to restore it<\/code><\/pre>\n\n\n\n<p>Given that the calling convention on x86_64 is to pass arguments to functions using registers&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/X86_calling_conventions#System_V_AMD64_ABI\">[15]<\/a>, the&nbsp;<code>__inst_profile<\/code>&nbsp;function expects that the argument will be in&nbsp;<code>rdi<\/code>. Obviously, we had to load the current instruction pointer adding some displacement to avoid jump back to the jump instruction!<\/p>\n\n\n\n<p>In the code above, we had taken advantage of the&nbsp;<code>RIP relative addressing<\/code>&nbsp;feature implemented in&nbsp;<code>x86_64<\/code>&nbsp;architecture. In practice,&nbsp;<code>rip<\/code>&nbsp;always points to the next instruction! Then we can\u2019t read directly it (only control-transfer function could do it), but we can load the address that it is referring to! If you are interested in the reasons that pushed to the introduction of rip relative addressing, read the article&nbsp;<a href=\"http:\/\/www.nynaeve.net\/?p=192\">[16]<\/a><\/p>\n\n\n\n<p>With all the ingredients of the recipe, we can introduce the plugin code! It is heavily similar to the one relative to GENERIC\/GIMPLE stuff for parts that regard registering the pass, attribute, and plugin info. But how the code is added is entirely different and based on RTL.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;gcc-plugin.h>\n#include &lt;rtl.h>\n#include &lt;target.h>\n#include &lt;tree.h>\n#include &lt;tree-pass.h>\n#include &lt;stringpool.h>\n#include &lt;attribs.h>\n#include &lt;memmodel.h>\n#include &lt;emit-rtl.h>\n\n\/**\n * When 1 enables verbose printing\n *\/\n#define DEBUG               1\n\n\/**\n * Name of the function called to profile code\n *\/\n#define FUNCTION_NAME       \"__inst_profile\"\n\n\/**\n * Name of the attribute used to instrument a function\n *\/\n#define ATTRIBUTE_NAME      \"profiled\"\n\n\/**\n * Name of this plugin\n *\/\n#define PLUGIN_NAME         \"inst_plugin\"\n\n\/**\n * Version of this plugin\n *\/\n#define PLUGIN_VERSION      \"0.1\"\n\n\/**\n * Help\/usage string for the plugin\n *\/\n#define PLUGIN_HELP         \"Usage: registers an attribute \" ATTRIBUTE_NAME\n\n\/**\n * Required GCC version\n *\/\n#define PLUGIN_GCC_BASEV    \"9.2.1\"\n\n\/\/ -----------------------------------------------------------------------------\n\/\/ GCC PLUGIN SETUP (BASIC INFO \/ LICENSE \/ REQUIRED VERSION)\n\/\/ -----------------------------------------------------------------------------\n\nint plugin_is_GPL_compatible;\n\n\/**\n * Additional information about the plugin. Used by --help and --version\n *\/\nstatic struct plugin_info inst_plugin_info =\n{\n  .version  = PLUGIN_VERSION,\n  .help     = PLUGIN_HELP,\n};\n\n\/**\n * Represents the gcc version we need. Used to void using an incompatible plugin \n *\/\nstatic struct plugin_gcc_version inst_plugin_ver =\n{\n  .basever  = PLUGIN_GCC_BASEV,\n};\n\n\/\/ -----------------------------------------------------------------------------\n\/\/ GCC EXTERNAL DECLARATION\n\/\/ -----------------------------------------------------------------------------\n\n\/**\n * Takes a tree node and returns the identifier string\n * @see https:\/\/gcc.gnu.org\/onlinedocs\/gccint\/Identifiers.html\n *\/\n#define FN_NAME(tree_fun) IDENTIFIER_POINTER (DECL_NAME (tree_fun))\n\n\/**\n * Takes a tree node and returns the identifier string length\n * @see https:\/\/gcc.gnu.org\/onlinedocs\/gccint\/Identifiers.html\n *\/\n#define FN_NAME_LEN(tree_fun) IDENTIFIER_LENGTH (DECL_NAME (tree_fun))\n\n\/**\n * Print GIMPLE statement G to FILE using SPC indentation spaces and FLAGS\n * @note Makes use of pp_gimple_stmt_1\n * @see Declared in gimple-pretty-print.h\n * @see Flags are listed in dumpfile.h\n *\/\nextern void print_gimple_stmt(FILE * file, gimple* g, int spc, dump_flags_t flags);\n\n\/**\n * Print tree T, and its successors, on file FILE. FLAGS specifies details to \n * show in the dump\n * @note Makes use of dump_generic_node\n * @see Declared in tree-pretty-print.h\n * @see Flags are listed in dumpfile.h\n *\/\nextern void print_generic_stmt(FILE* file, tree t, dump_flags_t flags);\n\n\/** \n * The global singleton context aka \"g\". The name is chosen to be easy to type\n * in a debugger. Represents the 'global state' of GCC\n * \n * GCC's internal state can be divided into zero or more \"parallel universe\" of \n * state; an instance of the class context is one such context of state\n * \n * @see Declared in context.h\n *\/\nextern gcc::context *g;\n\n\/\/ -----------------------------------------------------------------------------\n\/\/ GCC ATTRIBUTES MANAGEMENT (REGISTERING \/ CALLBACKS)\n\/\/ -----------------------------------------------------------------------------\n\n\/**\n * Insert a single ATTR into the attribute table\n * @see Declared in plugin.h\n * @note Insert the attribute into the 'gnu' attributes namespace\n *\/\nextern void register_attribute(const struct attribute_spec *attr);\n\n\/**\n * Attribute handler callback \n * @note NODE points to the node to which the attribute is to be applied. NAME \n * is the name of the attribute. ARGS is the TREE_LIST of arguments (may be \n * NULL). FLAGS gives information about the context of the attribute. \n * Afterwards, the attributes will be added unless *NO_ADD_ATTRS is set to true \n * (which should be done on error). Depending on FLAGS, any attributes to be \n * applied to another type or DECL later may be returned; otherwise the return \n * value should be NULL_TREE. This pointer may be NULL if no special handling is\n * required\n * @see Declared in tree-core.h\n *\/\nstatic tree handle_instrument_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs)\n{\n    #if DEBUG == 1\n        fprintf(stderr, \"> Found attribute\\n\");\n\n        fprintf(stderr, \"\\tnode = \");\n        print_generic_stmt(stderr, *node, TDF_NONE);\n        \n        fprintf(stderr, \"\\tname = \");\n        print_generic_stmt(stderr, name, TDF_NONE);\n    #endif\n\n    return NULL_TREE;\n}\n\n\/**\n * Structure describing an attribute and a function to handle it\n * @see Declared in tree-core.h\n * @note Refer to tree-core for docs about\n *\/\nstatic struct attribute_spec instrument_attr = {\n    ATTRIBUTE_NAME,                 \/* name *\/\n    0,                              \/* min_len *\/\n    0,                              \/* max_len *\/\n    false,                          \/* decl_req *\/\n    false,                          \/* type_req *\/\n    false,                           \/* fn_type_req *\/\n    false,                          \/* affects_type_identity *\/\n    handle_instrument_attribute,    \/* handler *\/\n    NULL                            \/* exclusions *\/\n};\n\n\/**\n * Plugin callback called during attribute registration \n *\/\nstatic void register_attributes(void *event_data, void *data)\n{\n    fprintf(stderr, \"> Registering attribute '%s'\\n\", ATTRIBUTE_NAME);\n    register_attribute(&amp;instrument_attr);\n}\n\n\/\/ -----------------------------------------------------------------------------\n\/\/ PLUGIN INSTRUMENTATION LOGICS\n\/\/ -----------------------------------------------------------------------------\n\n\/**\n * Generate RTL for asm code passed as STRING_CST and emit it after location loc \n * @note Heavily derived from GCC `expand_asm_loc` in `cfg_expand.c` \n *\/\nvoid expand_asm_after (tree string, int vol, rtx_insn * loc)\n{\n    rtx body;\n\n    body = gen_rtx_ASM_INPUT_loc (VOIDmode, ggc_strdup (TREE_STRING_POINTER (string)), INSN_LOCATION (loc));\n\n    MEM_VOLATILE_P (body) = vol;\n\n    \/* Non-empty basic ASM implicitly clobbers memory.  *\/\n    if (TREE_STRING_LENGTH (string) != 0)\n    {\n        rtx asm_op, clob;\n        unsigned i, nclobbers;\n        auto_vec&lt;rtx> input_rvec, output_rvec;\n        auto_vec&lt;const char *> constraints;\n        auto_vec&lt;rtx> clobber_rvec;\n        HARD_REG_SET clobbered_regs;\n        CLEAR_HARD_REG_SET (clobbered_regs);\n\n        clob = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));\n        clobber_rvec.safe_push (clob);\n\n        if (targetm.md_asm_adjust)\n            targetm.md_asm_adjust (output_rvec, input_rvec, constraints, clobber_rvec, clobbered_regs);\n\n        asm_op = body;\n        nclobbers = clobber_rvec.length ();\n        body = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (1 + nclobbers));\n\n        XVECEXP (body, 0, 0) = asm_op;\n        for (i = 0; i &lt; nclobbers; i++)\n            XVECEXP (body, 0, i + 1) = gen_rtx_CLOBBER (VOIDmode, clobber_rvec&#91;i]);\n    }\n\n    emit_insn_after_setloc (body, loc, INSN_LOCATION(loc));\n}\n\n\/**\n * Take a basic block as input and seek the insn list until the function prologue\n *\/\nrtx_insn* seek_till_fn_prologue(basic_block bb)\n{\n    rtx_insn *tmp_rtx;\n    \n    for (tmp_rtx = BB_HEAD(bb); tmp_rtx != 0; tmp_rtx = NEXT_INSN (tmp_rtx))\n  \t{\n        if ( (GET_CODE(tmp_rtx) == NOTE) &amp;&amp; (NOTE_KIND (tmp_rtx) == NOTE_INSN_FUNCTION_BEG))\n            break;\n    }\n\n    return tmp_rtx;\n}\n\n\/**\n * Create a function call to '__profile' and insert it before the given stmt\n *\/\nstatic void insert_instrumentation_fn(basic_block bb)\n{\n    char opcodes&#91;] = \n                    {\"\\\n                        push %rdi \\n \\\n                        lea 0x2(%rip), %rdi \\n \\\n                        jmp \" FUNCTION_NAME \" \\n \\\n                        pop %rdi \\\n                    \"};\n\n    tree string = build_string(strlen(opcodes), opcodes);\n\n    expand_asm_after(string, 1, BB_HEAD(bb));\n}\n\n\/**\n * For each function lookup attributes and attach profiling function\n *\/\nstatic unsigned int instrument_assignments_plugin_exec(void)\n{\n    \/\/ get the FUNCTION_DECL of the function whose body we are reading\n    tree fndef = current_function_decl;\n    \n    \/\/ print the function name\n    fprintf(stderr, \"> Inspecting function '%s'\\n\", FN_NAME(fndef));\n\n    \/\/ get the attributes list\n    tree attrlist = DECL_ATTRIBUTES(fndef);\n\n    \/\/ lookup into attribute list searcing for our registered attribute\n    tree attr = lookup_attribute(ATTRIBUTE_NAME, attrlist);\n\n    \/\/ if the attribute is not present\n    if (attr == NULL_TREE)\n        return 0;\n\n    \/\/ attribute was in the list\n    fprintf(stderr, \"\\t attribute %s found! \\n\", ATTRIBUTE_NAME);\n\n    \/\/ get function entry block\n    basic_block entry = ENTRY_BLOCK_PTR_FOR_FN(cfun)->next_bb;\n\n    \/\/ warn the user we are adding a profiling function\n    fprintf(stderr, \"\\t adding function jump after RTL: \");\n    print_rtl_single(stderr, BB_HEAD(entry));\n    \n    \/\/ insert the function\n    insert_instrumentation_fn(entry);\n\n    \/\/ when debugging, shows the rtl outputted\n    #if DEBUG == 1\n\n    fprintf(stderr, \"\\n> --------------------- \\n> - RTL AFTER \\n> --------------------- \\n\\n\");\n    print_rtl(stderr, BB_HEAD(entry));\n\n    #endif\n\n    \/\/ done!\n    return 0;\n}\n\n\/** \n * Metadata for a pass, non-varying across all instances of a pass\n * @see Declared in tree-pass.h\n * @note Refer to tree-pass for docs about\n *\/\nstruct pass_data ins_pass_data =\n{\n    .type = RTL_PASS,                                       \/\/ type of pass\n    .name = PLUGIN_NAME,                                    \/\/ name of plugin\n    .optinfo_flags = OPTGROUP_NONE,                         \/\/ no opt dump\n    .tv_id = TV_NONE,                                       \/\/ no timevar (see timevar.h)\n    .properties_required = 0,                               \/\/ no prop in input\n    .properties_provided = 0,                               \/\/ no prop in output\n    .properties_destroyed = 0,                              \/\/ no prop removed\n    .todo_flags_start = 0,                                  \/\/ need nothing before\n    .todo_flags_finish = 0                                  \/\/ need nothing after\n};\n\n\/**\n * Definition of our instrumentation RTL pass\n * @note Extends rtl_opt_pass class\n * @see Declared in tree-pass.h\n *\/\nclass ins_rtl_pass : public rtl_opt_pass\n{\npublic:\n\n    \/**\n     * Constructor\n     *\/\n    ins_rtl_pass (const pass_data&amp; data, gcc::context *ctxt) : rtl_opt_pass (data, ctxt) {}\n\n    \/**\n     * This and all sub-passes are executed only if the function returns true\n     * @note Defined in opt_pass father class\n     * @see Defined in tree-pass.h\n     *\/ \n    bool gate (function* gate_fun) \n    {\n        return true;\n    }\n\n    \/**\n     * This is the code to run when pass is executed\n     * @note Defined in opt_pass father class\n     * @see Defined in tree-pass.h\n     *\/\n    unsigned int execute(function* exec_fun)\n    {\n        return instrument_assignments_plugin_exec();\n    }\n};\n\n\/\/ instanciate a new instrumentation RTL pass\nins_rtl_pass inst_pass = ins_rtl_pass(ins_pass_data, g);\n\n\/\/ -----------------------------------------------------------------------------\n\/\/ PLUGIN INITIALIZATION\n\/\/ -----------------------------------------------------------------------------\n\n\/**\n * Initializes the plugin. Returns 0 if initialization finishes successfully. \n *\/\nint plugin_init(struct plugin_name_args *info, struct plugin_gcc_version *ver)\n{\n    \/\/ new pass that will be registered\n    struct register_pass_info pass;\n\n    \/\/ this plugin is compatible only with specified base ver\n    if (strncmp(inst_plugin_ver.basever, ver->basever, strlen(ver->basever)))\n        return 1;\n\n    \/\/ tell to GCC some info about this plugin\n    register_callback(PLUGIN_NAME, PLUGIN_INFO, NULL, &amp;inst_plugin_info);\n\n    \/\/ warn the user about the presence of this plugin\n    printf(\"> Instrumentation plugin '%s @ %s' was loaded onto GCC\\n\", PLUGIN_NAME, PLUGIN_VERSION);\n\n    \/\/ insert inst pass into the struct used to register the pass\n    pass.pass = &amp;inst_pass;\n\n    \/\/ get called after Control flow graph cleanup (see RTL passes)  \n    pass.reference_pass_name = \"*free_cfg\";\n\n    \/\/ after the first opt pass to be sure opt will not throw away our stuff\n    pass.ref_pass_instance_number = 1;\n    pass.pos_op = PASS_POS_INSERT_AFTER;\n\n    \/\/ add our pass hooking into pass manager\n    register_callback(PLUGIN_NAME, PLUGIN_PASS_MANAGER_SETUP, NULL, &amp;pass);\n\n    \/\/ get called at attribute registration\n    register_callback(PLUGIN_NAME, PLUGIN_ATTRIBUTES, register_attributes, NULL);\n\n    \/\/ everthing has worked\n    return 0;\n}<\/code><\/pre>\n\n\n\n<p>Let\u2019s try to compile it and compile the target program.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>> --------------------- \n> - RTL AFTER \n> --------------------- \n(note 3 1 22 &#91;bb 2] NOTE_INSN_BASIC_BLOCK)    # beginning of the function\n(insn 22 3 13 (parallel &#91;\n            (asm_input\/v (\"...                # asm outputted\n(insn\/f 13 22 14 (set (mem:DI (pre_dec:DI     # push %rbp\n...\n(note 16 15 2 NOTE_INSN_PROLOGUE_END)\n(note 2 16 5 NOTE_INSN_FUNCTION_BEG)\n...<\/code><\/pre>\n\n\n\n<p>It seems that it worked. Let\u2019s check the disassembly, and let\u2019s try it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>0000000000001149 &lt;__inst_profile&gt;:\n    1149:\tf3 0f 1e fa          \tendbr64 \n    114d:\t48 89 fb             \tmov    %rdi,%rbx\n    1150:\t48 8d 3d ad 0e 00 00 \tlea    0xead(%rip),%rdi        # 2004 &lt;_IO_stdin_used+0x4&gt;\n    1157:\te8 f4 fe ff ff       \tcallq  1050 &lt;puts@plt&gt;\n    115c:\tff e3                \tjmpq   *%rbx\n    115e:\t90                   \tnop\n    115f:\t0f 0b                \tud2    \n\n0000000000001161 &lt;f1&gt;:\n    1161:\tf3 0f 1e fa          \tendbr64 \n    1165:\t57                   \tpush   %rdi\n    1166:\t48 8d 3d 02 00 00 00 \tlea    0x2(%rip),%rdi        # 116f &lt;f1+0xe&gt;\n    116d:\teb da                \tjmp    1149 &lt;__inst_profile&gt;\n    116f:\t5f                   \tpop    %rdi\n    1170:\t55                   \tpush   %rbp\n    1171:\t48 89 e5             \tmov    %rsp,%rbp\n    1174:\tc7 45 fc 05 00 00 00 \tmovl   $0x5,-0x4(%rbp)\n    117b:\t83 45 fc 05          \taddl   $0x5,-0x4(%rbp)\n    117f:\t90                   \tnop\n    1180:\t5d                   \tpop    %rbp\n    1181:\tc3                   \tretq   \n<\/code><\/pre>\n\n\n\n<p>Before the function prologue, the exact ASM opcode we wrote was outputted and then at&nbsp;<code>1170<\/code>&nbsp;starts the function prologue.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>$<\/strong> .\/bin\nI'm a target C program.\nDo something here!\n<\/code><\/pre>\n\n\n\n<p>Hooray! We got precisely the point! Now we can do whatever we want to instrument the program and maybe adding some consistency check or something.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"4-documentation\">4.&nbsp;<a><\/a>Documentation<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"41-bibliography--document-cited\">4.1.&nbsp;<a><\/a>Bibliography &amp; document cited<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>GCC Wiki &#8211; Plugins\u00a0<a href=\"https:\/\/gcc.gnu.org\/wiki\/plugins\">[1]<\/a><\/li>\n\n\n\n<li><em>Matt Davis<\/em>\u00a0&#8211; An introduction to creating GCC plugins\u00a0<a href=\"https:\/\/lwn.net\/Articles\/457543\/\">[2]<\/a><\/li>\n\n\n\n<li><em>Fabian Scherschel<\/em>\u00a0&#8211; GCC 4.8 completes migration to C++\u00a0<a href=\"http:\/\/www.h-online.com\/news\/item\/GCC-4-8-completes-migration-to-C-1824539.html\">[3]<\/a><\/li>\n\n\n\n<li><em>Chris von Eitzen<\/em>\u00a0&#8211; GCC allows C++ \u2013 to some degree\u00a0<a href=\"http:\/\/www.h-online.com\/open\/news\/item\/GCC-allows-C-to-some-degree-1012611.html\">[4]<\/a><\/li>\n\n\n\n<li><em>Mark Mitchell<\/em>\u00a0&#8211; Using C++ in GCC is OK\u00a0<a href=\"https:\/\/gcc.gnu.org\/legacy-ml\/gcc\/2010-05\/msg00705.html\">[5]<\/a><\/li>\n\n\n\n<li><em>David Malcolm<\/em>\u00a0&#8211; Add -fno-rtti when building plugins\u00a0<a href=\"https:\/\/gcc.gnu.org\/legacy-ml\/gcc-patches\/2013-07\/msg01258.html\">[6]<\/a><\/li>\n\n\n\n<li>GCC Online Docs &#8211; Options Controlling C++ Dialect\u00a0<a href=\"https:\/\/gcc.gnu.org\/onlinedocs\/gcc-4.4.7\/gcc\/C_002b_002b-Dialect-Options.html\">[7]<\/a><\/li>\n\n\n\n<li><em>Sangwan Kwon<\/em>\u00a0&#8211; An Overview of GCC\u00a0<a href=\"http:\/\/bitboom.github.io\/an-overview-of-gcc\">[8]<\/a><\/li>\n\n\n\n<li><em>Pop S\u00e9bastian<\/em>\u00a0&#8211; AST representation in GCC\u00a0<a href=\"http:\/\/icps.u-strasbg.fr\/~pop\/gcc-ast.html\">[9]<\/a><\/li>\n\n\n\n<li><em>Jens Vankeirsbilck<\/em>\u00a0&#8211; CFED GCC Plugin\u00a0<a href=\"https:\/\/github.com\/MGroupKULeuvenBrugesCampus\/CFED_Plugin\">[10]<\/a><\/li>\n\n\n\n<li><em>Uday Khedker<\/em>\u00a0&#8211; Introduction to RTL\u00a0<a href=\"https:\/\/www.cse.iitb.ac.in\/~uday\/courses\/cs715-09\/gcc-rtl.pdf\">[11]<\/a><\/li>\n\n\n\n<li>GCC Online Docs &#8211; Passes and Files of the Compiler\u00a0<a href=\"https:\/\/gcc.gnu.org\/onlinedocs\/gccint\/Passes.html\">[12]<\/a><\/li>\n\n\n\n<li>GCC Online Docs &#8211; RTL Object Types\u00a0<a href=\"https:\/\/gcc.gnu.org\/onlinedocs\/gccint\/RTL-Objects.html#RTL-Objects\">[13]<\/a><\/li>\n\n\n\n<li>GCC Online Docs &#8211; Side Effect Expressions\u00a0<a href=\"https:\/\/gcc.gnu.org\/onlinedocs\/gccint\/Side-Effects.html#Side-Effects\">[14]<\/a><\/li>\n\n\n\n<li>Wikipedia.org &#8211; System V AMD64 ABI\u00a0<a href=\"https:\/\/en.wikipedia.org\/wiki\/X86_calling_conventions#System_V_AMD64_ABI\">[15]<\/a><\/li>\n\n\n\n<li><em>Ken Johnson<\/em>\u00a0&#8211; Most data references in x64 are RIP-relative\u00a0<a href=\"http:\/\/www.nynaeve.net\/?p=192\">[16]<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>https:\/\/gabrieleserra.ml\/blog\/2020-08-27-an-introduction-to-gcc-and-gccs-plugins.html 1.&nbsp;Brief introduction to GNU\u2019s GCC The GNU toolchain is [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[21,10],"class_list":["post-133","post","type-post","status-publish","format-standard","hentry","category-tutotial","tag-gcc_plugin","tag-toolchain"],"_links":{"self":[{"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/posts\/133","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/haco.club\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=133"}],"version-history":[{"count":1,"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/posts\/133\/revisions"}],"predecessor-version":[{"id":134,"href":"https:\/\/haco.club\/index.php?rest_route=\/wp\/v2\/posts\/133\/revisions\/134"}],"wp:attachment":[{"href":"https:\/\/haco.club\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=133"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/haco.club\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=133"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/haco.club\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=133"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}