[PATCH v1 02/14] Object Attributes v2: new abstractions for subsections and attributes
Matthieu Longo
matthieu.longo@arm.com
Fri Mar 21 17:14:36 GMT 2025
From: Richard Ball <richard.ball@arm.com>
This patch lays the groundwork for the support of Object Attributes v2 (OAv2).
OAv2 is an enhancement of OAv1. They retain successful aspects of OAv1, define
the relationship between object attributes and existing GNU properties, separate
architectural requirements from software ABI requirements, and simplify the
format to make it easier for OAv2 consumers to parse, and skip subsections and
attributes. Interestingly, OAv2 have only one scope: the whole relocatable file
where they were specified. For the reason behind this choice, see [1], "Build
attributes at file scope only". This document also provides more insights into
the design rationale for OAv2.
Even if OAv2 was designed primarily for AArch64, this implementation splits the
generic core logic from the backend-specific one, and aims at facilitating OAv2
adoption by others backend. This logic will apply for any subsequent OAv2 patch.
New abstractions for attributes and subsections are introduced in bfd/elf-attrs.h
Those align with the format of OAv2 proposed in [2].
An object attribute obj_attr_v2 is a key-value pair:
- key: a tag id, i.e. a unique identifier for the attribute in the
subsection.
- value: a variant for which the interpretation depends on the encoding
set in the subsection it was stored in. 2 types of values are possible:
ULEB128 (Unsigned Little Endian Base 128) or a string encoded as NTBS
(Null-Terminated Byte String).
A subsection obj_attr_subsection_v2 has the following members:
- name: the name of this subsection.
- scope: the prefix in the subsection name determines whether the
subsection is public or private.
- optionality: is this subsection optional or required ? Depending on
whether the subsection is public or private, it can be ignored by the
consumer.
- encoding: see previous note regarding the value of an attribute. This
encoding applies to all the attributes in this subsection.
- list of object attributes.
Even if OAv1 and OAv2 data structures are similar, their processing is
different. Thus refactoring the code of OAv1 and OAv2 to share it does not
seem the right approach for clarity and maintainability, and minimalization
of the risk of introducing regressions.
Consequently, utility functions to initialize, copy, swap, free, compare,
mutate, and sort those structures won't be shared between OAv1 and OAv2.
Finally, the version of attributes that the backend support (default is set
to OAv1), and a list of subsections for OAv2 are added to elf_backend_data.
AArch64 backend is the only one for now to set the version to OAv2.
[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)
Co-Authored-By: Matthieu Longo <matthieu.longo@arm.com>
---
bfd/Makefile.am | 2 +-
bfd/Makefile.in | 2 +-
bfd/elf-attrs.c | 208 +++++++++++++++++++++++++++++++++++++++++
bfd/elf-attrs.h | 102 ++++++++++++++++++++
bfd/elf-bfd.h | 42 ++++++++-
bfd/elfnn-aarch64.c | 13 +++
bfd/elfxx-target.h | 6 +-
bfd/po/SRC-POTFILES.in | 1 +
8 files changed, 371 insertions(+), 5 deletions(-)
create mode 100644 bfd/elf-attrs.h
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 4987ac9cccc..0339db6b2b6 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -707,7 +707,7 @@ SOURCE_HFILES = \
elf32-metag.h elf32-nds32.h elf32-ppc.h \
elf32-rx.h elf32-score.h elf32-sh-relocs.h elf32-spu.h \
elf32-tic6x.h elf32-tilegx.h elf32-tilepro.h elf32-v850.h \
- elf64-hppa.h elf64-ppc.h elf64-tilegx.h \
+ elf64-hppa.h elf64-ppc.h elf64-tilegx.h elf-attrs.h \
elf-bfd.h elfcode.h elfcore.h elf-hppa.h elf-linker-x86.h \
elf-linux-core.h elf-nacl.h elf-s390.h elf-vxworks.h \
elfxx-aarch64.h elfxx-ia64.h elfxx-mips.h elfxx-riscv.h \
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index 1543af7984a..ecc91d733af 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -1171,7 +1171,7 @@ SOURCE_HFILES = \
elf32-metag.h elf32-nds32.h elf32-ppc.h \
elf32-rx.h elf32-score.h elf32-sh-relocs.h elf32-spu.h \
elf32-tic6x.h elf32-tilegx.h elf32-tilepro.h elf32-v850.h \
- elf64-hppa.h elf64-ppc.h elf64-tilegx.h \
+ elf64-hppa.h elf64-ppc.h elf64-tilegx.h elf-attrs.h \
elf-bfd.h elfcode.h elfcore.h elf-hppa.h elf-linker-x86.h \
elf-linux-core.h elf-nacl.h elf-s390.h elf-vxworks.h \
elfxx-aarch64.h elfxx-ia64.h elfxx-mips.h elfxx-riscv.h \
diff --git a/bfd/elf-attrs.c b/bfd/elf-attrs.c
index e80575b9a55..e58f47b2c43 100644
--- a/bfd/elf-attrs.c
+++ b/bfd/elf-attrs.c
@@ -20,6 +20,7 @@
#include "sysdep.h"
#include "bfd.h"
+#include "double-linked-list.h"
#include "libiberty.h"
#include "libbfd.h"
#include "elf-bfd.h"
@@ -476,6 +477,19 @@ gnu_obj_attrs_arg_type (unsigned int tag)
int
_bfd_elf_obj_attrs_arg_type (bfd *abfd, int vendor, unsigned int tag)
{
+ if (get_elf_backend_data (abfd)->obj_attrs_version == 2)
+ {
+ BFD_ASSERT (elf_obj_attr_subsections (abfd).last_ != NULL);
+ switch (elf_obj_attr_subsections (abfd).last_->encoding)
+ {
+ case ULEB128:
+ return ATTR_TYPE_FLAG_INT_VAL;
+ case NTBS:
+ return ATTR_TYPE_FLAG_STR_VAL;
+ }
+ }
+
+ /* Version 1. */
switch (vendor)
{
case OBJ_ATTR_PROC:
@@ -818,6 +832,200 @@ _bfd_elf_merge_unknown_attribute_list (bfd *ibfd, bfd *obfd)
return result;
}
+obj_attr_v2 *
+_bfd_elf_obj_attr_v2_init (unsigned int tag,
+ union obj_attr_value_v2 vals)
+{
+ obj_attr_v2 *attr = (obj_attr_v2*) malloc (sizeof (obj_attr_v2));
+ memset ((void *) attr, 0, sizeof (obj_attr_v2));
+ attr->tag = tag;
+ attr->vals = vals;
+ return attr;
+}
+
+void
+_bfd_elf_obj_attr_v2_free (obj_attr_v2 * attr, obj_attr_encoding_v2 encoding)
+{
+ if (encoding == NTBS && attr->vals.string_val != NULL)
+ free ((void *) attr->vals.string_val);
+ free (attr);
+}
+
+obj_attr_v2 *
+_bfd_elf_obj_attr_v2_copy (obj_attr_v2 *other,
+ obj_attr_encoding_v2 encoding)
+{
+ union obj_attr_value_v2 vals;
+ if (encoding == NTBS)
+ vals.string_val =
+ (other->vals.string_val != NULL)
+ ? strdup (other->vals.string_val)
+ : NULL;
+ else
+ vals.uint_val = other->vals.uint_val;
+
+ obj_attr_v2 *copy =_bfd_elf_obj_attr_v2_init (other->tag, vals);
+ return copy;
+}
+
+#define SWAP(a, b) do { typeof(a) temp = a; a = b; b = temp; } while (0)
+
+void
+_bfd_elf_obj_attr_v2_swap (obj_attr_subsection_v2 *s,
+ obj_attr_v2 *a1, obj_attr_v2 *a2)
+{
+ SWAP (a1->next, a2->next);
+ SWAP (a1->prev, a2->prev);
+
+ if (s->first_ == a1)
+ s->first_ = a2;
+ else if (s->first_ == a2)
+ s->first_ = a1;
+
+ if (s->last_ == a1)
+ s->last_ = a2;
+ else if (s->last_ == a2)
+ s->last_ = a1;
+}
+
+int
+_bfd_elf_obj_attr_v2_cmp (obj_attr_v2 *a1, obj_attr_v2 *a2)
+{
+ if (a1->tag < a2->tag)
+ return -1;
+ else if (a1->tag > a2->tag)
+ return 1;
+ else
+ return 0;
+}
+
+/* Find the object attribute matching the given tag (object attributes v2 only).
+ Note: The parameter 'sorted' specifies whether the given list is sorted or
+ not. If the list of attributes is sorted, the linear search stops as soon as
+ it finds an attribute with a greater tag. */
+obj_attr_v2 *
+obj_attr_v2_find_by_tag (obj_attr_subsection_v2 *subsec,
+ uint32_t tag,
+ bool sorted)
+{
+ for (obj_attr_v2 *attr = subsec->first_;
+ attr != NULL;
+ attr = attr->next)
+ if (attr->tag == tag)
+ return attr;
+ else if (sorted && attr->tag > tag)
+ break;
+ return NULL;
+}
+
+LINKED_LIST_MUTATIVE_OPS_DECL(obj_attr_subsection_v2, obj_attr_v2, /* public */)
+LINKED_LIST_MERGE_SORT_DECL(obj_attr_subsection_v2, obj_attr_v2, /* public */)
+
+obj_attr_subsection_v2 *
+_bfd_elf_obj_attr_subsection_v2_init (const char* name,
+ obj_attr_subsection_scope_v2 scope,
+ bool optional,
+ obj_attr_encoding_v2 encoding)
+{
+ obj_attr_subsection_v2* subsection = (obj_attr_subsection_v2*)
+ malloc (sizeof (obj_attr_subsection_v2));
+ memset ((void *) subsection, 0, sizeof (obj_attr_subsection_v2));
+ subsection->name = name;
+ subsection->scope = scope;
+ subsection->optional = optional;
+ subsection->encoding = encoding;
+ return subsection;
+}
+
+void
+_bfd_elf_obj_attr_subsection_v2_free (obj_attr_subsection_v2 *subsec)
+{
+ for (obj_attr_v2 *attr = subsec->first_; attr != NULL; attr = attr->next)
+ _bfd_elf_obj_attr_v2_free (attr, subsec->encoding);
+ free (subsec);
+}
+
+obj_attr_subsection_v2 *
+_bfd_elf_obj_attr_subsection_v2_copy (obj_attr_subsection_v2 const *other)
+{
+ obj_attr_subsection_v2* new_subsec =
+ _bfd_elf_obj_attr_subsection_v2_init (other->name, other->scope,
+ other->optional, other->encoding);
+ for (obj_attr_v2* attr = other->first_;
+ attr != NULL;
+ attr = attr->next)
+ {
+ obj_attr_v2* new_attr = _bfd_elf_obj_attr_v2_copy (attr, other->encoding);
+ LINKED_LIST_APPEND(obj_attr_v2) (new_subsec, new_attr);
+ }
+ return new_subsec;
+}
+
+void
+_bfd_elf_obj_attr_subsection_v2_swap (obj_attr_subsection_list *plist,
+ obj_attr_subsection_v2 *s1,
+ obj_attr_subsection_v2 *s2)
+{
+ SWAP (s1->next, s2->next);
+ SWAP (s1->prev, s2->prev);
+
+ if (plist->first_ == s1)
+ plist->first_ = s2;
+ else if (plist->first_ == s2)
+ plist->first_ = s1;
+
+ if (plist->last_ == s1)
+ plist->last_ = s2;
+ else if (plist->last_ == s2)
+ plist->last_ = s1;
+}
+
+int
+_bfd_elf_obj_attr_subsection_v2_cmp (obj_attr_subsection_v2 *s1,
+ obj_attr_subsection_v2 *s2)
+{
+ int res = strcmp (s1->name, s2->name);
+ if (res != 0)
+ return res;
+
+ if (s1->optional < s2->optional)
+ return -1;
+ else if (s1->optional > s2->optional)
+ return 1;
+
+ if (s1->encoding < s2->encoding)
+ return -1;
+ if (s1->encoding > s2->encoding)
+ return 1;
+ else
+ return 0;
+}
+
+/* Find the subsection matching the given name.
+ Note: The parameter sorted specified whether the given list is sorted or not.
+ If the list of subsections is sorted, the linear search stops as soon as it
+ finds a subsection name with a greater order. */
+obj_attr_subsection_v2 *
+obj_attr_subsection_v2_find_by_name (obj_attr_subsection_v2 *first,
+ const char *name,
+ bool sorted)
+{
+ for (obj_attr_subsection_v2 *s = first;
+ s != NULL;
+ s = s->next)
+ {
+ int cmp = strcmp (s->name, name);
+ if (cmp == 0)
+ return s;
+ else if (sorted && cmp > 0)
+ break;
+ }
+ return NULL;
+}
+
+LINKED_LIST_MUTATIVE_OPS_DECL(obj_attr_subsection_list, obj_attr_subsection_v2, /* public */)
+LINKED_LIST_MERGE_SORT_DECL(obj_attr_subsection_list, obj_attr_subsection_v2, /* public */)
+
bool _bfd_elf_write_section_build_attributes (bfd *abfd,
struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
diff --git a/bfd/elf-attrs.h b/bfd/elf-attrs.h
new file mode 100644
index 00000000000..5d41bb98538
--- /dev/null
+++ b/bfd/elf-attrs.h
@@ -0,0 +1,102 @@
+/* ELF attributes support (based on ARM EABI attributes).
+ Copyright (C) 2025 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#pragma once
+
+#include <stdint.h>
+
+/* --------------------
+ Object attributes v2
+ -------------------- */
+
+typedef enum obj_attr_encoding_v2
+{
+ ULEB128 = 0,
+ NTBS = 1,
+} obj_attr_encoding_v2;
+
+typedef union obj_attr_value_v2 {
+ uint32_t uint_val;
+ const char* string_val;
+} obj_attr_value_v2;
+
+typedef struct obj_attr_v2 {
+ /* The name/tag of an attribute. */
+ uint32_t tag;
+
+ /* The value assigned to an attribute, can be ULEB128 or NTBS. */
+ union obj_attr_value_v2 vals;
+
+ /* The next attribute in the list or NULL. */
+ struct obj_attr_v2 *next;
+
+ /* The previous attribute in the list or NULL. */
+ struct obj_attr_v2 *prev;
+
+} obj_attr_v2;
+
+typedef enum obj_attr_subsection_scope_v2
+{
+ SUBSEC_PUBLIC = 0,
+ SUBSEC_PRIVATE = 1,
+} obj_attr_subsection_scope_v2;
+
+typedef struct obj_attr_subsection_v2 {
+ /* The name of the subsection. */
+ const char *name;
+
+ /* The scope of the subsection. */
+ obj_attr_subsection_scope_v2 scope;
+
+ /* Is this subsection optional ? Can it be skipped ? */
+ bool optional;
+
+ /* The value encoding of attributes in this subsection. */
+ obj_attr_encoding_v2 encoding;
+
+ /* The next subsection in the list, or NULL. */
+ struct obj_attr_subsection_v2 *next;
+
+ /* The previous subsection in the list, or NULL. */
+ struct obj_attr_subsection_v2 *prev;
+
+ /* A pointer to the first node of the list. */
+ struct obj_attr_v2* first_;
+
+ /* A pointer to the last node of the list. */
+ struct obj_attr_v2* last_;
+
+ /* The size of the list. */
+ uint32_t size;
+
+} obj_attr_subsection_v2;
+
+typedef struct obj_attr_subsection_list
+{
+ /* A pointer to the first node of the list. */
+ obj_attr_subsection_v2 *first_;
+
+ /* A pointer to the last node of the list. */
+ obj_attr_subsection_v2 *last_;
+
+ /* The size of the list. */
+ uint64_t size;
+} obj_attr_subsection_list;
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 5903d857faa..6c326d5db72 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -24,9 +24,11 @@
#include <stdlib.h>
+#include "double-linked-list.h"
#include "elf/common.h"
#include "elf/external.h"
#include "elf/internal.h"
+#include "elf-attrs.h"
#include "bfdlink.h"
#ifndef ENABLE_CHECKING
@@ -1630,13 +1632,15 @@ struct elf_backend_data
/* The section name to use for a processor-standard attributes section. */
const char *obj_attrs_section;
- /* Return 1, 2 or 3 to indicate what type of arguments a
- processor-specific tag takes. */
+ /* Return 1, 2 or 3 to indicate what type of arguments a tag takes. */
int (*obj_attrs_arg_type) (int);
/* The section type to use for an attributes section. */
unsigned int obj_attrs_section_type;
+ /* The version of object attributes (1 or 2). */
+ unsigned int obj_attrs_version;
+
/* This function determines the order in which any attributes are
written. It must be defined for input in the range
LEAST_KNOWN_OBJ_ATTRIBUTE..NUM_KNOWN_OBJ_ATTRIBUTES-1 (this range
@@ -2160,6 +2164,11 @@ struct elf_obj_tdata
obj_attribute known_obj_attributes[2][NUM_KNOWN_OBJ_ATTRIBUTES];
obj_attribute_list *other_obj_attributes[2];
+ /* Object attributes v2: attributes of the same category are stored inside
+ the same subsection. A subsection can only hold attributes with the same
+ data type. */
+ obj_attr_subsection_list obj_attr_subsections;
+
/* Linked-list containing information about every Systemtap section
found in the object file. Each section corresponds to one entry
in the list. */
@@ -2253,6 +2262,7 @@ struct elf_obj_tdata
(elf_known_obj_attributes (bfd) [OBJ_ATTR_PROC])
#define elf_other_obj_attributes_proc(bfd) \
(elf_other_obj_attributes (bfd) [OBJ_ATTR_PROC])
+#define elf_obj_attr_subsections(bfd) (elf_tdata (bfd) -> obj_attr_subsections)
#define elf_properties(bfd) (elf_tdata (bfd) -> properties)
#define elf_has_no_copy_on_protected(bfd) \
(elf_tdata(bfd) -> has_no_copy_on_protected)
@@ -3083,6 +3093,34 @@ extern bool _bfd_elf_merge_unknown_attribute_list (bfd *, bfd *);
extern Elf_Internal_Shdr *_bfd_elf_single_rel_hdr (asection *sec);
extern bool elf_read_notes (bfd *, file_ptr, bfd_size_type, size_t);
+extern obj_attr_v2 *_bfd_elf_obj_attr_v2_init (unsigned int,
+ union obj_attr_value_v2);
+extern void _bfd_elf_obj_attr_v2_free (obj_attr_v2 *, obj_attr_encoding_v2);
+extern obj_attr_v2 *_bfd_elf_obj_attr_v2_copy (obj_attr_v2 *,
+ obj_attr_encoding_v2);
+extern void _bfd_elf_obj_attr_v2_swap (obj_attr_subsection_v2 *,
+ obj_attr_v2 *, obj_attr_v2 *);
+extern int _bfd_elf_obj_attr_v2_cmp (obj_attr_v2 *, obj_attr_v2 *);
+extern obj_attr_v2 *
+obj_attr_v2_find_by_tag (obj_attr_subsection_v2 *, uint32_t, bool);
+LINKED_LIST_MUTATIVE_OPS_PROTOTYPE(obj_attr_subsection_v2, obj_attr_v2, extern);
+_LINKED_LIST_MERGE_SORT_PROTOTYPE(obj_attr_v2, extern);
+LINKED_LIST_MERGE_SORT_PROTOTYPE(obj_attr_subsection_v2, obj_attr_v2, extern);
+extern obj_attr_subsection_v2 *_bfd_elf_obj_attr_subsection_v2_init (const char*,
+ obj_attr_subsection_scope_v2, bool, obj_attr_encoding_v2);
+extern void _bfd_elf_obj_attr_subsection_v2_free (obj_attr_subsection_v2 *);
+extern obj_attr_subsection_v2 *_bfd_elf_obj_attr_subsection_v2_copy
+ (obj_attr_subsection_v2 const*);
+extern void _bfd_elf_obj_attr_subsection_v2_swap (obj_attr_subsection_list *,
+ obj_attr_subsection_v2 *, obj_attr_subsection_v2 *);
+extern int _bfd_elf_obj_attr_subsection_v2_cmp (obj_attr_subsection_v2 *,
+ obj_attr_subsection_v2 *s2);
+extern obj_attr_subsection_v2 * obj_attr_subsection_v2_find_by_name
+ (obj_attr_subsection_v2 *, const char *, bool);
+LINKED_LIST_MUTATIVE_OPS_PROTOTYPE(obj_attr_subsection_list, obj_attr_subsection_v2, extern);
+_LINKED_LIST_MERGE_SORT_PROTOTYPE(obj_attr_subsection_v2, extern);
+LINKED_LIST_MERGE_SORT_PROTOTYPE(obj_attr_subsection_list, obj_attr_subsection_v2, extern);
+
extern bool _bfd_elf_parse_gnu_properties
(bfd *, Elf_Internal_Note *);
extern elf_property_list * _bfd_elf_find_property
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 548da1f8b30..21fc99c4c98 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -10760,8 +10760,21 @@ const struct elf_size_info elfNN_aarch64_size_info =
#define elf_backend_extern_protected_data 0
#define elf_backend_hash_symbol elf_aarch64_hash_symbol
+/* elf_backend_obj_attrs_vendor is unused for AArch64. It is replaced by the
+ concept of subsections, each one having its own name defined by the
+ assembly directive "aeabi_subsection". */
+#undef elf_backend_obj_attrs_vendor
+#define elf_backend_obj_attrs_vendor "aeabi"
#undef elf_backend_obj_attrs_section
#define elf_backend_obj_attrs_section SEC_AARCH64_ATTRIBUTES
+/* elf_backend_obj_attrs_arg_type is unused as the type of an attribute is
+ determined by looking up at the current subsection, not the value of the
+ tag. */
+#define elf_backend_obj_attrs_arg_type NULL
+#undef elf_backend_obj_attrs_section_type
+#define elf_backend_obj_attrs_section_type SHT_AARCH64_ATTRIBUTES
+#undef elf_backend_obj_attrs_version
+#define elf_backend_obj_attrs_version 2
#include "elfNN-target.h"
diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
index 625243cac94..cff508dbbce 100644
--- a/bfd/elfxx-target.h
+++ b/bfd/elfxx-target.h
@@ -556,6 +556,9 @@
#ifndef elf_backend_obj_attrs_section_type
#define elf_backend_obj_attrs_section_type SHT_GNU_ATTRIBUTES
#endif
+#ifndef elf_backend_obj_attrs_version
+#define elf_backend_obj_attrs_version 1 /* Default version. */
+#endif
#ifndef elf_backend_obj_attrs_order
#define elf_backend_obj_attrs_order NULL
#endif
@@ -808,7 +811,7 @@
#ifndef elf_backend_symbol_section_index
#define elf_backend_symbol_section_index NULL
#endif
-
+
#ifndef elf_match_priority
#define elf_match_priority \
(ELF_ARCH == bfd_arch_unknown ? 2 : ELF_OSABI == ELFOSABI_NONE ? 1 : 0)
@@ -934,6 +937,7 @@ static const struct elf_backend_data elfNN_bed =
elf_backend_obj_attrs_section,
elf_backend_obj_attrs_arg_type,
elf_backend_obj_attrs_section_type,
+ elf_backend_obj_attrs_version,
elf_backend_obj_attrs_order,
elf_backend_obj_attrs_handle_unknown,
elf_backend_parse_gnu_properties,
diff --git a/bfd/po/SRC-POTFILES.in b/bfd/po/SRC-POTFILES.in
index 54b078b8295..4b8ccfbe2c8 100644
--- a/bfd/po/SRC-POTFILES.in
+++ b/bfd/po/SRC-POTFILES.in
@@ -132,6 +132,7 @@ ecoff.c
ecofflink.c
ecoffswap.h
elf-attrs.c
+elf-attrs.h
elf-bfd.h
elf-eh-frame.c
elf-hppa.h
--
2.49.0
More information about the Binutils
mailing list