ANNOBIN(1)
okay bestie, we're in the annobin(1) manual from the RPM Development Tools crew π it's giving main character energy, so let's get into it π
β¨ NAME β¨
annobin - Annobin π¦
πΈ SYNOPSIS πΈ
okay this one's literally empty, no cap π nothing to see here
π DESCRIPTION π
Binary Annotation is a method for recording info about an application inside the application itself π«Ά It's an implementation of the "Watermark" specification, which lives at https://fedoraproject.org/wiki/Toolchain/Watermark π
Okay so, it's mainly about recording security info, but the system can store any kind of data, even stuff that has nothing to do with the app β¨ One of the big goals is being able to say exactly which address range a piece of info is valid for. So for example, you could say a whole program was compiled with -O2 except for one special function that got -O0 instead π iconic behavior, honestly.
The range info is super useful because third parties can poke at the binary and check whether it was built consistently π i.e. there are no gaps in the recorded info, and no sneaky special cases where a required feature wasn't active π€
The system works by adding special sections to the application. Each one holds an individual piece of info along with the address range where it's valid. (Some serious effort went into storing all this in a reasonably compact format π)
The info is generated by a plugin attached to the compiler π§ The plugin pulls information out of the compiler's internals and records it in the object file(s) being produced.
Note, though: the plugin is just one way of generating the info. Any interested party can create and add info to the object file, as long as they follow the Watermark specification π
The info can be extracted with tools like readelf and objdump π§ The annobin package also includes a program called annocheck that can examine this info too. Details on it can be found elsewhere in this documentation π
Experience has shown that storing the range info along with the data tends to significantly increase program size π So the system also has an alternative implementation that uses a more compact format, at the cost of dropping the range data π
Normally the build system turns on recording of binary annotation notes automatically, so you don't have to do anything π On Fedora and RHEL based systems, this is handled by the redhat-rpm-config package π
Right now the binary annotations are generated by a plugin to the compiler (GCC, clang or llvm). That means files not compiled by any of these won't gain any annotations π There is an optional assembler switch that adds some basic notes if none are present in the input files, though π
If the build system you're using doesn't automatically enable the annobin plugin, you can add it to the compiler command line yourself with one of these:
-fplugin=annobinβ for gcc-fplugin=annobin-for-clangβ for clang-fplugin=annobin-for-llvmβ for LLVM
You might also need to tell the compiler where to find the plugin with -iplugindir=. Only do this if the plugin is installed somewhere unusual πΊ
Want to turn off recording? Use one of these:
-fplugin-arg-annobin-disableβ for "gcc"-Xclang -plugin-arg-annobin-disableβ for "clang" or "llvm"
These must be placed after the -fplugin=annobin option, bestie. Order matters π¨
On Fedora and RHEL systems, you can disable the plugin entirely for all compilations in a package by adding %undefine _annotated_build to the spec file π
The info is stored in the binary in one of two ways: either in ELF Note format inside a special section called .gnu.build.attributes, or as ordinary strings inside a section called .annobin.notes π§
The readelf program from the binutils package can extract and display these notes. Adding the --wide option is also helpful β¨
If the info is held in ELF note format, readelf's --notes option will display it. Here's an example of the output:
Displaying notes found in: .gnu.build.attributes
Owner Data size Description
GA$<version>3p3 0x00000010 OPEN Applies to region from 0x8a0 to 0x8c6 (hello.c)
GA$<tool>gcc 7.2.1 20170915 0x00000000 OPEN Applies to region from 0x8a0 to 0x8c6
GA*GOW:0x452b 0x00000000 OPEN Applies to region from 0x8a0 to 0x8c6
GA*<stack prot>strong 0x00000000 OPEN Applies to region from 0x8a0 to 0x8c6
GA*GOW:0x412b 0x00000010 func Applies to region from 0x8c0 to 0x8c6 (baz)
This shows all sorts of info πΈ including that the notes were made using version 3 of the specification, and version 3 of the plugin. The binary was built by gcc version 7.2.1, and the -fstack-protector-strong option was enabled on the command line. The program was compiled with -O2 enabled, except the baz() function, which was compiled with -O0 instead.
The most complicated part of the notes is the owner field π΅βπ« It's used to encode the type of note, its value, and possibly extra data too. The Watermark spec explains the format in detail, but basically it's the letters G and A, then an encoding character (one of *$!+), then a type character, and finally the value.
The notes are always four-byte aligned, even on 64-bit systems. This means consumers of the notes may have to read 8-byte wide values from 4-byte aligned addresses, and producers of the notes may have to generate unaligned relocs when creating them β οΈ
If the info is held as strings, readelf's -p.annobin.notes option will display them. Here's an example of that output:
String dump of section '.annobin.notes':
[ 0] AV:4.p.1200
[ c] RV:running gcc 12.2.1 20221121
[ 2b] BV:annobin gcc 12.2.1 20221121
[ 4a] PN:annobin
[ 55] GW:0x290540
[ 61] SP:3
β¨ OPTIONS β¨
Okay bestie, so the plugin has a whole menu of options π
You pass them with -fplugin-arg-annobin-<option> if you're on gcc, or -Xclang -plugin-arg-annobin-<option> if you're on clang or llvm π¦ They have to come after the plugin is mentioned on the command line, no cap. Also, not every version of the plugin takes every option, so check your version first π
You can also slip options in through the ANNOBIN environment variable πΈ Separate multiple arguments with commas, and anything that needs a value has to use an equals sign. Not a space, not a colon. Equals sign only, periodt.
For backwards compatibility, the LLVM plugin also checks for the ANNOBIN_VERBOSE environment variable, and if it's there, verbose mode turns on β¨
The supported options are:
disable,enableβ Turns the plugin off or on. It's enabled by default, so you only needdisableif you want it gone πhelpβ Prints a list of the supported options to standard output. It does this in addition to whatever else you asked the plugin to do π§versionβ Prints the plugin's version to standard output. Same deal, it happens on top of everything else πverboseβ Makes the plugin tell you what it's doing. Pass it a second time and it goes very verbose πfunction-verboseβ Reports when function specific notes get generated. This basically means that function was compiled with different options than the ones turned on globally πstack-size-notes,no-stack-size-notesβ Records (or doesn't record) info about how much stack each function needs in the executable. It's off by default because these notes can eat up a LOT of room if your executable has tons of functions πstack-threshold=Nβ Only works if stack size notes are being recorded. It sets the minimum to record: functions needing less than N bytes of static stack space get skipped. If you don't set it, N defaults to 1024 βglobal-file-syms,no-global-file-symsβ When enabled, this makes globally visible, unique symbols that mark the start and end of the compiled code π¦ This is super useful if your program has multiple source files with the same name, or if it links to a library built from source files that share a name with your program. The catch: the unique names are based on the time of the build, so building the same source again gives different symbol names. That breaks the build-id system, which is supposed to identify similar builds made at different times π₯Ί It's disabled by default, and you can turn it back off withno-global-file-syms.attach,no-attachβ When gcc compiles with-ffunction-sections, each function gets its own section. Withattachon, the plugin tries to attach that function section to a group holding the notes and relocations for that function π«Ά That way, if the linker decides to toss the function, it knows to toss the notes and relocations too.attachis the default, and you can disable it withno-attach. Heads up though: if bothattachandlink-orderare disabled, note generation for function sections won't work properly πlink-order,no-link-orderβ Instead of section groups plus a special assembler directive, the plugin can use the ELFSHF_LINK_ORDERflag. This tells the linker to discard a section if the section it's linked to is also being discarded. Turn it on withlink-orderπrename[=STR]β Adds an extra prefix to the symbol names the plugin generates. This lets you run the plugin twice on the same executable, which is handy for debugging and build testing π§ͺ The default prefix is.1, but you can change it by giving this option a string argument.
Note: if you don't use rename, the plugin will try to detect and disable multiple copies of itself. Prior to version 12.72, however, that detection only works reliably if the annobin plugin is the first plugin specified on the gcc command line β οΈ
active-checks,no-active-checksβ By default the plugin warns you if it notices certain preprocessor command line options are missing or misspelt πactive-checksturns those warnings into errors, just like if you'd specified-Werror.no-active-checksshuts the messages up entirely.
Right now, the plugin checks for these:
Missing FORTIFY_SOURCEβ Warns when neither-D_FORTIFY_SOURCE=2nor-D_FORTIFY_SOURCE=3is on the command line and-fltois enabled. Normally the annocheck tool would catch this, but LTO compilation hides preprocessor options, so the plugin can't pass that info along. That's why it warns you when_FORTIFY_SOURCEis missing and LTO is on π‘οΈ-D_FORTIFY_SOURCE typoβ Warns if-D_FORTIFY_SOURCEis spelt as either-DFORTIFY_SOURCEor-D__FORTIFY_SOURCEπ€-D_GLIBCXX_ASSERTIONS typoβ Warns if-D_GLIBCXX_ASSERTIONSis spelt as either-DGLIBCXX_ASSERTIONSor-D__GLIBCXX_ASSERTIONSπ€
The plugin might get more of these warnings for other missing command line options in the future π
Also, as a workaround for certain tests generated by the autoconf tool, the warning won't be produced if the input source filename starts with conftest.. Autoconf is usually just checking whether a warning would be produced for some other reason, and the annobin warning would get in the way. If active-checks is enabled, though, an error message still gets generated π«
dynamic-notes,no-dynamic-notes,static-notes,no-static-notesβ These are deprecated π
Deprecated: these options are no longer recommended. Try not to build new stuff around them π
ppc64-nops,no-ppc64-nopsβ Turns on or off the insertion of NOP instructions in some of the code sections of PowerPC64 binaries π This is needed to avoid problems with theelflintprogram, which will complain about binaries built without it. It's enabled by default, but since it makes compiled programs a little bigger,no-ppc64-nopsis there if you want to turn it off.note-format="note"|"string"β Picks the format used to store the information the plugin generates β¨ The options are:noteβ Stores the info as ELF format notes in the.gnu.build.attributessection.stringβ Stores the info as mergeable strings in the.annobin.notessection.
The default is note π
π COPYRIGHT π
Copyright (c) 2018-2026 Red Hat. π
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation, with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License" π
And that's the whole page, bestie π«Ά This one comes from annobin-1, dated 2026-02-23. Go forth and compile something iconic π β¨
π¦ where this page comes from
- centos-stream 10: annobin-docs 13.31-1.el10 Β· GPL-3.0-or-later AND LGPL-2.0-or-later AND (GPL-2.0-or-later WITH GCC-exception-2.0) AND (LGPL-2.0-or-later WITH GCC-exception-2.0) AND GFDL-1.3-or-later
- centos-stream 9: annobin 13.29-1.el9 Β· GPL-3.0-or-later AND LGPL-2.0-or-later AND (GPL-2.0-or-later WITH GCC-exception-2.0) AND (LGPL-2.0-or-later WITH GCC-exception-2.0) AND GFDL-1.3-or-later
- fedora 44: annobin-docs 13.08-1.fc44 Β· GPL-3.0-or-later AND LGPL-2.0-or-later AND (GPL-2.0-or-later WITH GCC-exception-2.0) AND (LGPL-2.0-or-later WITH GCC-exception-2.0) AND GFDL-1.3-or-later
- fedora 44: annobin-docs 13.14-1.fc44 Β· GPL-3.0-or-later AND LGPL-2.0-or-later AND (GPL-2.0-or-later WITH GCC-exception-2.0) AND (LGPL-2.0-or-later WITH GCC-exception-2.0) AND GFDL-1.3-or-later
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms