3 How to examine the information stored in the binary.

The information is stored in a binary in either the ELF Note format inside a special section called .gnu.build.attributes, or else 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 information is held in the ELF note format then readelf’s --notes option will display them. Here is 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 various different pieces of information, including the fact that the notes were produced 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. This is used to encode the type of note as well as its value and possibly extra data as well. The format of the field is explained in detail in the Watermark specification, but it basically consists of the letters ‘G’ and ‘A’ followed by an encoding character (one of ‘*$!+’) and then a type character and finally the value.

The notes are always four byte aligned, even on 64-bit systems. This does mean that consumers of the notes may have to read 8-byte wide values from 4-byte aligned addresses, and that producers of the notes may have to generate unaligned relocs when creating them.

If the information is held as strings then readelf’s -p.annobin.notes option will display them. Here is an example of the 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

Most of the notes have a reasonably self explanatory name and value. The exception are the version and GOW notes, which are included in the table below.