[v0,00/15] AArch64 AEABI build attributes (a.k.a. object attributes v2)

Message ID 20250310175131.1217374-1-matthieu.longo@arm.com
Headers
Series AArch64 AEABI build attributes (a.k.a. object attributes v2) |

Message

Matthieu Longo March 10, 2025, 5:51 p.m. UTC
  Hi all,

This patch series introduces support for AArch64 AEABI build attributes (that I will refer as Object Attributes V2). Build attributes are metadata embedded in ELF object files, and binaries (executables, and shared linkable libraries) to provide ABI and compatibility information. These attributes help linkers to diagnose incompatibilities and enforce compatibility between the input object files at link time. Additionally, they can offer insights into the targeted processor, or architecture for an object file, or features used in it. More details can be found in [1] and Section 4 of [2].

## Background and Motivation

The initial implementation of build attributes (that I will refer as Object Attributes V1) dates back to 2005 ([3]) and is specified in [4]. It stores attributes in a vendor-specific section ".ARM.attribute" using a complex format based on <tag, value> pairs and sub-subsections, where the key determines whether the attributes is mandatory or optional, and whether the type of the value is an integer encoded as ULEB128 (Unsigned Little Endian Base 128) or a string encoded as NTBS (Null-Terminated Byte String). While widely adopted since 2007 ([5]), Object Attributes V1's complexity makes parsing and skipping subsections or attributes challenging, especially for the main consumers, the linkers, which are responsible to merge them, and enforce compatibility.

To address these limitations, a new specification for AArch64 build attributes (Object Attributes V2) was proposed ([1], [2]). Key design goals include:
- Retaining successful aspects of Object Attributes V1.
- Defining the relationship between build attributes and the existing GNU program properties.
- Separating architectural requirements from software ABI requirements.
- Simplifying the format to allow consumers to skip a subsection or attribute that it does not understand without giving a warning message.

The specification is available in [2], and a pull request for discussion is open at [6].

Example of the new AArch64 assembly directives to declare subsections and attributes:
```
.aeabi_subsection aeabi_feature_and_bits, optional, uleb128
.aeabi_attribute  Tag_Feature_BTI, 1
.aeabi_attribute  Tag_Feature_GCS, 1
```

Output of readelf:
```
Displaying notes found in: .note.gnu.property
  Owner                Data size 	Description
  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0
      Properties: AArch64 feature: BTI, GCS
Subsections:
 - Name:	aeabi_feature_and_bits
   Scope:	public
   Length:	33
   Optional:	True
   Encoding:	ULEB128
   Values:
    Tag_Feature_BTI:	1 (0x1)
    Tag_Feature_GCS:	1 (0x1)
```

## Patch Series Overview

This series consists of 15 patches, structured in 5 blocks as follows:
1. Patch 1 introduces a "generic" doubly linked list implementation in libiberty, used in the following patches to manage subsections and their attributes.
2. Patches 2-7 add serialization support in gas, and dumping capabilities in readelf:
   * 2 new assembly directives for AArch64: ".aeabi_subsection" and ".aeabi_attribute".
   * convertion from assembly to internal abstractions.
   * serialization in bfd.
   * dumping support in readelf.
   * tests for serialization and dumping.
3. Patches 8-11 implement deserialization, copy support for objcopy, and add tests for copying.
4. Patch 12 implements the generic framework so that the linker can convert GNU properties to object attributes V2, merge them, and re-convert them to GNU properties. Patch 13 adds the corresponding generic tests.
5. Patch 14 implements the support for AArch64 AEABI build attributes and BTI, PAC and GCS tagging similar to what currently exists with the GNU properties. Patch 15 adds the corresponding AArch64-specific tests.

Regression testing on aarch64-unknown-linux-gnu showed no failures.

Regarding the nested functions ([7]), I plan to reorganize the code to eliminate them in a future version of this patch series.

Feedback, questions, and change proposals are welcome.

Regards,
Matthieu.

## References

[1]: [Design Rationale for Build Attributes for the Arm 64-bit Architecture (AARCH64)](https://github.com/ARM-software/abi-aa/blob/eec881270d5e3b23e58a6250640d06ff545ec1fc/design-documents/buildattr64-rationale.rst)
[2]: [Build Attributes for the ArmĀ® 64-bit Architecture (AArch64)](https://github.com/ARM-software/abi-aa/blob/eec881270d5e3b23e58a6250640d06ff545ec1fc/buildattr64/buildattr64.rst)
[3]: [\[patch\] Arm EABI object attributes, by Paul Brook - September 2005](https://sourceware.org/pipermail/binutils/2005-September/044310.html)
[4]: [Addenda to, and Errata in, the ABI for the ARM Architecture (AArch32) - Chapter 3 - ADDENDUM: Build Attributes](https://github.com/ARM-software/abi-aa/blob/a82eef0433556b30539c0d4463768d9feb8cfd0b/addenda32/addenda32.rst#addendum-build-attributes)
[5]: [Object attribute tagging, by Joseph S. Myers - June 2007](https://gcc.gnu.org/legacy-ml/gcc/2007-06/msg00654.html)
[6]: [PR #230: AArch64 build attributes specification](https://github.com/ARM-software/abi-aa/pull/230)
[7]: [Removing nested function from elfxx-aarch64.c](https://inbox.sourceware.org/binutils/98c5819b-d197-4fdb-aa7f-9fd52801cad8@redhat.com/)



Matthieu Longo (10):
  libiberty: add implementations of common methods for type-sensitive doubly linked lists
  gas/write.c: add missing flag SEC_HAS_CONTENT on object attributes section
  bfd: parse build attributes v2's section in input object files
  bfd: add support for copying object attributes v2
  objcopy tests: copy accurately build attributes data from an object to another
  bfd: merge duplicated subsections into one after parsing
  ld's BAs merge saga, step one: generic merge works on its own without backend support
  ld tests: generic merge coverage for build attributes
  ld's BAs merge saga, step two: AArch64 backend's support for AEABI-specific BAs
  ld tests: AArch64-specific merge coverage for AEABI-specific BAs

Richard Ball (5):
  Build attributes: add new abstractions for subsections and attributes
  gas: parse object attributes v2
  bfd: write object attributes v2
  readelf: add support to dump build attributes v2
  gas tests: add new tests for build attributes

 bfd/Makefile.am                               |    2 +-
 bfd/Makefile.in                               |    2 +-
 bfd/elf-attrs.c                               | 2060 ++++++++++++++++-
 bfd/elf-attrs.h                               |  196 ++
 bfd/elf-bfd.h                                 |   76 +-
 bfd/elf.c                                     |   22 +-
 bfd/elfnn-aarch64.c                           |  114 +-
 bfd/elfxx-aarch64.c                           |  306 ++-
 bfd/elfxx-aarch64.h                           |   36 +
 bfd/elfxx-target.h                            |   38 +-
 bfd/po/SRC-POTFILES.in                        |    1 +
 binutils/readelf.c                            |  261 +++
 .../binutils-all/aarch64/build-attributes.d   |   52 +
 .../binutils-all/aarch64/build-attributes.s   |   31 +
 gas/config/obj-elf.c                          |  411 ++++
 gas/config/obj-elf.h                          |   27 +
 gas/config/tc-aarch64.c                       |  102 +
 gas/config/tc-aarch64.h                       |    5 +
 .../aarch64-build-attributes.exp              |   23 +
 .../gas/aarch64/build-attributes/ba-1.d       |   51 +
 .../gas/aarch64/build-attributes/ba-1.s       |   30 +
 .../aarch64/build-attributes/ba-failures-1.d  |   14 +
 .../aarch64/build-attributes/ba-failures-1.s  |   28 +
 .../ba-interleaved-subsections.d              |   35 +
 .../ba-interleaved-subsections.s              |   32 +
 .../build-attributes/ba-subsection-parsing.d  |   75 +
 .../build-attributes/ba-subsection-parsing.s  |   21 +
 gas/write.c                                   |    4 +-
 include/double-linked-list.h                  |  313 +++
 include/elf/aarch64.h                         |   13 +
 ld/ldelf.c                                    |    1 +
 .../aarch64-build-attributes.exp              |   47 +
 .../build-attributes/ba-1-all-optional-1.s    |   15 +
 .../build-attributes/ba-1-all-optional-2.s    |   15 +
 ...ismatch-subsec-props-with-all-optional-1.d |    7 +
 ...ismatch-subsec-props-with-all-optional-1.s |    2 +
 .../build-attributes/ba-1-one-file.d          |   42 +
 ...-1-two-files-all-optional-1more-1missing.d |   53 +
 ...nknown-and-known-attr-known-subsection-1.s |   11 +
 ...nknown-and-known-attr-known-subsection-2.s |   11 +
 ...-unknown-and-known-attr-known-subsection.d |   25 +
 ...ba-2-mix-unknown-and-known-subsections-1.s |   19 +
 ...ba-2-mix-unknown-and-known-subsections-2.s |   19 +
 .../ba-2-mix-unknown-and-known-subsections.d  |   26 +
 .../ba-2-required-subsec-A-1.s                |    3 +
 .../ba-2-required-subsec-A-2.s                |    3 +
 .../build-attributes/ba-2-required-subsec-B.s |    3 +
 .../ba-2-required-subsec-nok.d                |    7 +
 .../ba-2-required-subsec-ok.d                 |   16 +
 .../build-attributes/ba-aarch64-1-bti-1.s     |    9 +
 .../build-attributes/ba-aarch64-1-bti-2.s     |   14 +
 ...a-aarch64-1-bti-explicit-ok-objdump-dump.d |   53 +
 ...a-aarch64-1-bti-explicit-ok-readelf-dump.d |   24 +
 ...t-only-one-input-without-ba-or-gnu-props.d |   19 +
 ...-gnu-props-only-implicit-ok-readelf-dump.d |   20 +
 ...-aarch64-1-bti-implicit-nok-objdump-dump.d |   45 +
 ...-aarch64-1-bti-implicit-nok-readelf-dump.d |   16 +
 ...a-aarch64-1-bti-implicit-ok-objdump-dump.d |   38 +
 ...a-aarch64-1-bti-implicit-ok-readelf-dump.d |   19 +
 .../ba-aarch64-1-bti-via-gnu-props.s          |   11 +
 ...u-props-and-bas-implicit-ok-readelf-dump.d |   22 +
 .../build-attributes/ba-aarch64-1-gcs-1.s     |    9 +
 .../build-attributes/ba-aarch64-1-gcs-2.s     |   14 +
 ...a-aarch64-1-gcs-explicit-ok-readelf-dump.d |   24 +
 ...-gnu-props-only-implicit-ok-readelf-dump.d |   20 +
 ...-aarch64-1-gcs-implicit-nok-readelf-dump.d |   16 +
 ...a-aarch64-1-gcs-implicit-ok-readelf-dump.d |   19 +
 .../ba-aarch64-1-gcs-via-gnu-props.s          |   11 +
 .../build-attributes/ba-aarch64-1-no-bti.s    |    2 +
 .../build-attributes/ba-aarch64-1-no-gcs.s    |    2 +
 .../build-attributes/ba-aarch64-1-pac-1.s     |    9 +
 .../build-attributes/ba-aarch64-1-pac-2.s     |   14 +
 ...rch64-1-pac-ba-with-pac-plt-objdump-dump.d |   44 +
 ...rch64-1-pac-ba-with-pac-plt-readelf-dump.d |   21 +
 ...64-1-pac-ba-without-pac-plt-objdump-dump.d |   38 +
 ...64-1-pac-ba-without-pac-plt-readelf-dump.d |   21 +
 ...h64-1-pac-plt-but-no-pac-ba-objdump-dump.d |   53 +
 ...h64-1-pac-plt-but-no-pac-ba-readelf-dump.d |   18 +
 .../ba-aarch64-1-pac-via-gnu-props.s          |   11 +
 .../ba-aarch64-1-required-subsection-1.s      |    7 +
 .../ba-aarch64-1-required-subsection-2.s      |    7 +
 ...aarch64-1-required-subsection-mismatch-1.s |    7 +
 ...aarch64-1-required-subsection-mismatch-2.s |    7 +
 .../ba-aarch64-1-required-subsection-nok-1.d  |    7 +
 .../ba-aarch64-1-required-subsection-nok-2.d  |    9 +
 .../ba-aarch64-1-required-subsection-ok.d     |   25 +
 .../ba-aarch64-1-unknown-tag.d                |   20 +
 .../ba-aarch64-1-unknown-tag.s                |    3 +
 .../build-attributes/ba-aarch64-1-void.s      |    5 +
 .../ld-aarch64/build-attributes/bti-plt.ld    |   14 +
 .../gnu-note-properties-maskable-merged.inc   |   32 +
 .../gnu-note-properties-maskable-split.inc    |   72 +
 .../gnu-note-properties-selectable-merged.inc |   32 +
 .../gnu-note-properties-selectable-split.inc  |   72 +
 libiberty/Makefile.in                         |    1 +
 libiberty/testsuite/Makefile.in               |   12 +-
 libiberty/testsuite/test-linked-list.c        |  244 ++
 97 files changed, 5825 insertions(+), 93 deletions(-)
 create mode 100644 bfd/elf-attrs.h
 create mode 100644 binutils/testsuite/binutils-all/aarch64/build-attributes.d
 create mode 100644 binutils/testsuite/binutils-all/aarch64/build-attributes.s
 create mode 100644 gas/testsuite/gas/aarch64/build-attributes/aarch64-build-attributes.exp
 create mode 100644 gas/testsuite/gas/aarch64/build-attributes/ba-1.d
 create mode 100644 gas/testsuite/gas/aarch64/build-attributes/ba-1.s
 create mode 100644 gas/testsuite/gas/aarch64/build-attributes/ba-failures-1.d
 create mode 100644 gas/testsuite/gas/aarch64/build-attributes/ba-failures-1.s
 create mode 100644 gas/testsuite/gas/aarch64/build-attributes/ba-interleaved-subsections.d
 create mode 100644 gas/testsuite/gas/aarch64/build-attributes/ba-interleaved-subsections.s
 create mode 100644 gas/testsuite/gas/aarch64/build-attributes/ba-subsection-parsing.d
 create mode 100644 gas/testsuite/gas/aarch64/build-attributes/ba-subsection-parsing.s
 create mode 100644 include/double-linked-list.h
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/aarch64-build-attributes.exp
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-1-all-optional-1.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-1-all-optional-2.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-1-mismatch-subsec-props-with-all-optional-1.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-1-mismatch-subsec-props-with-all-optional-1.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-1-one-file.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-1-two-files-all-optional-1more-1missing.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-2-mix-unknown-and-known-attr-known-subsection-1.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-2-mix-unknown-and-known-attr-known-subsection-2.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-2-mix-unknown-and-known-attr-known-subsection.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-2-mix-unknown-and-known-subsections-1.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-2-mix-unknown-and-known-subsections-2.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-2-mix-unknown-and-known-subsections.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-2-required-subsec-A-1.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-2-required-subsec-A-2.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-2-required-subsec-B.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-2-required-subsec-nok.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-2-required-subsec-ok.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-bti-1.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-bti-2.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-bti-explicit-ok-objdump-dump.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-bti-explicit-ok-readelf-dump.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-bti-explicit-only-one-input-without-ba-or-gnu-props.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-bti-gnu-props-only-implicit-ok-readelf-dump.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-bti-implicit-nok-objdump-dump.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-bti-implicit-nok-readelf-dump.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-bti-implicit-ok-objdump-dump.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-bti-implicit-ok-readelf-dump.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-bti-via-gnu-props.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-bti-with-mix-gnu-props-and-bas-implicit-ok-readelf-dump.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-gcs-1.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-gcs-2.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-gcs-explicit-ok-readelf-dump.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-gcs-gnu-props-only-implicit-ok-readelf-dump.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-gcs-implicit-nok-readelf-dump.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-gcs-implicit-ok-readelf-dump.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-gcs-via-gnu-props.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-no-bti.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-no-gcs.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-pac-1.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-pac-2.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-pac-ba-with-pac-plt-objdump-dump.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-pac-ba-with-pac-plt-readelf-dump.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-pac-ba-without-pac-plt-objdump-dump.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-pac-ba-without-pac-plt-readelf-dump.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-pac-plt-but-no-pac-ba-objdump-dump.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-pac-plt-but-no-pac-ba-readelf-dump.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-pac-via-gnu-props.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-required-subsection-1.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-required-subsection-2.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-required-subsection-mismatch-1.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-required-subsection-mismatch-2.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-required-subsection-nok-1.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-required-subsection-nok-2.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-required-subsection-ok.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-unknown-tag.d
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-unknown-tag.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/ba-aarch64-1-void.s
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/bti-plt.ld
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/gnu-note-properties-maskable-merged.inc
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/gnu-note-properties-maskable-split.inc
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/gnu-note-properties-selectable-merged.inc
 create mode 100644 ld/testsuite/ld-aarch64/build-attributes/gnu-note-properties-selectable-split.inc
 create mode 100644 libiberty/testsuite/test-linked-list.c