summaryrefslogtreecommitdiffstats
path: root/tools/gcc-plugins/README.md
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tools/gcc-plugins/README.md102
1 files changed, 102 insertions, 0 deletions
diff --git a/tools/gcc-plugins/README.md b/tools/gcc-plugins/README.md
new file mode 100644
index 0000000..ab31d0e
--- /dev/null
+++ b/tools/gcc-plugins/README.md
@@ -0,0 +1,102 @@
+frr-format GCC plugin
+=====================
+
+Context
+-------
+
+This plugin provides improved type checking for Linux kernel style printf
+extensions (i.e. `%pI4` printing `struct in_addr *` as `1.2.3.4`.)
+
+Other than additional warnings, (non-)usage of this plugin should not affect
+the build outcome. It is perfectly fine to build FRR without this plugin.
+
+
+Binary Debian packages
+----------------------
+
+Can be found at [https://deb.nox.tf/devel/].
+
+
+GCC requirements
+----------------
+
+To use this plugin, you need a **patched 9.3.0** or a **patched 10.1.0**
+version of GCC using the [gcc-retain-typeinfo.patch] provided in this repo.
+
+Without this patch, GCC strips type information too early during compilation,
+leaving to the plugin being unable to perform more meaningful type checks.
+(Specifically, all `typedef` casts will be "cooked down" to their final type.)
+If the patch is missing, `format-test.c` will show 4 false negative/positive
+warnings marked with `(need retain-typeinfo patch)`.
+
+(@eqvinox has discussed this one-line diff with some GCC people on their
+IRC channel around mid 2019, the consensus was that the line is an "early
+optimization" and removing it should not be harmful. However, doing so is
+likely to break GCC's unit tests since warnings would print different types.)
+
+Other versions of gcc are not supported. gcc 8 previously did work but isn't
+actively tested/maintained.
+
+
+Usage
+-----
+
+First, all plugin-specific statements should be wrapped by an ifdef:
+
+```
+#ifdef _FRR_ATTRIBUTE_PRINTFRR
+...
+#endif
+```
+
+`_FRR_ATTRIBUTE_PRINTFRR` will be defined to the plugin's version (currently
+0x10000) whenever the plugin is loaded.
+
+Then, annotate extended printf functions with the `frr_format` attribute.
+This works exactly like the `format` attribute:
+
+```
+int printfn(const char *fmt, ...) __attribute__((frr_format("frr_printf", 1, 2)));
+```
+
+In the FRR codebase, use the `PRINTFRR` macro provided in
+[../../lib/compiler.h].
+
+Lastly, "declare" extensions with `#pragma FRR printfrr_ext`:
+```
+#ifdef _FRR_ATTRIBUTE_PRINTFRR
+#pragma FRR printfrr_ext "%pI4" (struct in_addr *)
+#pragma FRR printfrr_ext "%pI4" (in_addr_t *)
+#endif
+```
+
+Note that you can use multiple such lines if a particular extended printer
+works for more than one type (as seen above.)
+
+The pragma type "parameter" looks like a C cast but unfortunately due to GCC
+not exporting a good interface to proper type parsing, it is "ghetto parsed",
+with only `struct`, `union`, `enum` being properly supported. `const` is
+ignored if it occurs as the first token. (The plugin always accepts `const`
+parameters for printf since printf shouldn't change the passed data it's
+printing.) The last token may be zero or more counts of `*`, note that
+qualifiers on the intermediate pointers (e.g. `const char * const *`) are not
+supported.
+
+
+TODOs and future direction
+--------------------------
+
+* support two-parameter extension printers that use the precision field
+ (e.g. `"%.*pI5" (int af, void *addr)` to print an IP address with the
+ address family in the "precision".
+
+* port to future GCC versions
+
+* get the one-liner patch upstreamed
+
+
+License
+-------
+
+This plugin is **derivative of GCC 9.x**. It was created by copying off
+`c-format.c`. It must therefore adhere to GCC's GPLv3+ license.