[PATCH v3 23/26] gnu directives: add support for gnu_attribute and gnu_subsection in OAv2 context
Matthieu Longo
matthieu.longo@arm.com
Fri May 9 15:13:13 GMT 2025
This patch adds support for the GNU directives .gnu_attribute and
.gnu_subsection, used respectively for OAv1 and OAv2, and for OAv2 only.
These directives behave like their AEABI counterparts, as they are aliases
intended for use by any backends supporting OAv1 and/or OAv2. Their
availability is controlled by the SUPPORT_OAv1 and SUPPORT_OAv2 macros,
which are defined via TC_<target>.
Previously, the "gnu" subsection namespace was used only for
"gnu-testing" and defaulted to a private scope. This patch updates the
scope recognition to correctly distinguish between private usage (e.g.,
testing) and public usage (e.g., actual GNU subsections storing public
information).
---
bfd/elf-attrs.c | 9 +++++----
binutils/readelf.c | 4 +++-
gas/config/obj-elf.c | 30 +++++++++++++++++++++++++++++-
gas/obj-attr.c | 10 +++++-----
gas/obj-attr.h | 25 +++++++++++++++++++++++++
5 files changed, 67 insertions(+), 11 deletions(-)
diff --git a/bfd/elf-attrs.c b/bfd/elf-attrs.c
index 73bd0d93fdc..0df746872f0 100644
--- a/bfd/elf-attrs.c
+++ b/bfd/elf-attrs.c
@@ -2408,10 +2408,11 @@ bfd_elf_parse_attrs_subsection_v2 (bfd *abfd,
}
const char *vendor_name = get_elf_backend_data (abfd)->obj_attrs_vendor;
- obj_attr_subsection_scope_v2 scope =
- (strncmp (subsection_name, vendor_name, strlen (vendor_name)) == 0)
- ? OA_SUBSEC_PUBLIC
- : OA_SUBSEC_PRIVATE;
+ obj_attr_subsection_scope_v2 scope = OA_SUBSEC_PRIVATE;
+ if (strncmp (subsection_name, vendor_name, strlen (vendor_name)) == 0
+ || (strncmp (subsection_name, "gnu", 3) == 0
+ && strncmp (subsection_name + 3, "-testing", 8) != 0))
+ scope = OA_SUBSEC_PUBLIC;
obj_attr_subsection_v2 *subsec =
_bfd_elf_obj_attr_subsection_v2_init (subsection_name, scope, optional_raw,
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 08a05840a70..269145e80fb 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -19646,7 +19646,9 @@ elf_parse_attrs_subsection_v2 (unsigned char *cursor,
const char *subsec_name = (const char *) cursor;
printf (_(" - Name: %s\n"), subsec_name);
bool public_subsection =
- strncmp (subsec_name, public_name, strlen (public_name)) == 0;
+ strncmp (subsec_name, public_name, strlen (public_name)) == 0
+ || (strncmp (subsec_name, "gnu", 3) == 0
+ && strncmp (subsec_name + 3, "-testing", 8) != 0);
cursor += subsection_name_len;
op.read += subsection_name_len;
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index 8db8d1d6bc8..82e999c89ec 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -72,7 +72,12 @@ static void obj_elf_visibility (int);
static void obj_elf_symver (int);
static void obj_elf_subsection (int);
static void obj_elf_popsection (int);
+#if (SUPPORT_OAv1 || SUPPORT_OAv2)
static void obj_elf_gnu_attribute (int);
+#endif
+#if SUPPORT_OAv2
+static void obj_elf_gnu_subsection (int);
+#endif
static void obj_elf_tls_common (int);
static void obj_elf_lcomm (int);
static void obj_elf_struct (int);
@@ -117,7 +122,12 @@ static const pseudo_typeS elf_pseudo_table[] =
{"vtable_entry", obj_elf_vtable_entry, 0},
/* A GNU extension for object attributes. */
+#if (SUPPORT_OAv1 || SUPPORT_OAv2)
{"gnu_attribute", obj_elf_gnu_attribute, 0},
+#endif
+#if (SUPPORT_OAv2)
+ {"gnu_subsection", obj_elf_gnu_subsection, 0},
+#endif
/* These are used for dwarf2. */
{ "file", dwarf2_directive_file, 0 },
@@ -2058,12 +2068,30 @@ obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED)
}
/* Parse a .gnu_attribute directive. */
-
+#if (SUPPORT_OAv1 || SUPPORT_OAv2)
static void
obj_elf_gnu_attribute (int ignored ATTRIBUTE_UNUSED)
{
obj_attr_process_attribute (OBJ_ATTR_GNU);
}
+#endif
+
+/* Parse a .gnu_subsection directive. */
+#if (SUPPORT_OAv2)
+static void
+obj_elf_gnu_subsection (int ignored ATTRIBUTE_UNUSED)
+{
+ obj_attr_version_t version = elf_obj_attr_version (stdoutput);
+ if (version < OBJ_ATTR_V2)
+ {
+ as_bad (_(".gnu_subsection is only available with object attributes v2,"
+ " and the current target only supports object attributes v1"));
+ ignore_rest_of_line ();
+ return;
+ }
+ obj_attr_process_subsection ();
+}
+#endif
void
elf_obj_read_begin_hook (void)
diff --git a/gas/obj-attr.c b/gas/obj-attr.c
index 91d3693f090..88b975839c3 100644
--- a/gas/obj-attr.c
+++ b/gas/obj-attr.c
@@ -18,7 +18,6 @@
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
-#include "as.h"
#include "obj-attr.h"
#include "obstack.h"
#include "safe-ctype.h"
@@ -905,10 +904,11 @@ obj_attr_v2_subsection_record (const char *name,
{
const char *vendor_name =
get_elf_backend_data (stdoutput)->obj_attrs_vendor;
- obj_attr_subsection_scope_v2 scope =
- (strncmp (name, vendor_name, strlen (vendor_name)) == 0)
- ? OA_SUBSEC_PUBLIC
- : OA_SUBSEC_PRIVATE;
+ obj_attr_subsection_scope_v2 scope = OA_SUBSEC_PRIVATE;
+ if (strncmp (name, vendor_name, strlen (vendor_name)) == 0
+ || (strncmp (name, "gnu", 3) == 0
+ && strncmp (name + 3, "-testing", 8) != 0))
+ scope = OA_SUBSEC_PUBLIC;
obj_attr_subsection_v2 *new_subsection =
_bfd_elf_obj_attr_subsection_v2_init (name, scope, optional, encoding);
diff --git a/gas/obj-attr.h b/gas/obj-attr.h
index 51662ab82df..7d005f7189a 100644
--- a/gas/obj-attr.h
+++ b/gas/obj-attr.h
@@ -21,8 +21,33 @@
#ifndef _OBJ_ATTR_H
#define _OBJ_ATTR_H
+#include "as.h"
#include "bfd/elf-bfd.h"
+/* The target supports Object Attributes v1. */
+#if (defined(TC_ARC) \
+ || defined(TC_ARM) \
+ || defined(TC_CSKY) \
+ || defined(TC_M68K) \
+ || defined(TC_MIPS) \
+ || defined(TC_MSP430) \
+ || defined(TC_PPC) \
+ || defined(TC_RISCV) \
+ || defined(TC_S390) \
+ || defined(TC_SPARC) \
+ || defined(TC_TIC6X))
+#define SUPPORT_OAv1 1
+#else
+#define SUPPORT_OAv1 0
+#endif
+
+/* The target supports Object Attributes v2. */
+#if defined(TC_AARCH64)
+#define SUPPORT_OAv2 1
+#else
+#define SUPPORT_OAv2 0
+#endif
+
/* Object attributes v1. */
extern void obj_attr_v1_rai_enter (void);
extern void obj_attr_v1_rai_exit (void);
--
2.49.0
More information about the Binutils
mailing list