[PATCH v11 22/25] gnu directives: add support for .gnu_attribute and .gnu_subsection in OAv2 context
Matthieu Longo
matthieu.longo@arm.com
Tue Dec 30 23:05:23 GMT 2025
More information about the Binutils mailing list
Tue Dec 30 23:05:23 GMT 2025
- Previous message (by thread): [PATCH v11 21/25] ld tests for AArch64-specific merge coverage for AEABI Build Attributes
- Next message (by thread): [PATCH v11 23/25] gnu directives: gas/readelf tests for gnu attributes v2
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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 TC_OBJ_ATTR_v1
and TC_OBJ_ATTR_v2 macros.
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 | 6 ++-
binutils/readelf.c | 6 ++-
gas/config/obj-elf-attr.c | 34 ++++++++++++
gas/config/obj-elf-attr.h | 3 ++
gas/config/obj-elf.c | 3 ++
gas/doc/as.texi | 105 +++++++++++++++++++++++++++++++-------
6 files changed, 135 insertions(+), 22 deletions(-)
diff --git a/bfd/elf-attrs.c b/bfd/elf-attrs.c
index 72e679485f3..04bb074e90b 100644
--- a/bfd/elf-attrs.c
+++ b/bfd/elf-attrs.c
@@ -611,8 +611,10 @@ bfd_elf_obj_attr_subsection_v2_scope (const bfd *abfd, const char *subsec_name)
const char *vendor_name = get_elf_backend_data (abfd)->obj_attrs_vendor;
obj_attr_subsection_scope_v2_t scope = OA_SUBSEC_PRIVATE;
size_t vendor_name_len = strlen (vendor_name);
- if (strncmp (subsec_name, vendor_name, vendor_name_len) == 0
- && subsec_name[vendor_name_len] == '_')
+ if ((strncmp (subsec_name, vendor_name, vendor_name_len) == 0
+ && subsec_name[vendor_name_len] == '_')
+ || (strncmp (subsec_name, "gnu_", 4) == 0
+ && !gnu_testing_namespace (subsec_name)))
scope = OA_SUBSEC_PUBLIC;
return scope;
}
diff --git a/binutils/readelf.c b/binutils/readelf.c
index dfb6152c132..78b3233b331 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -20098,8 +20098,10 @@ elf_parse_attrs_subsection_v2 (unsigned char *cursor,
bfd_elf_obj_attr_subsection_v2_scope() in bfd/elf-attrs.c. */
size_t public_name_len = strlen (public_name);
bool public_subsection
- = strncmp (subsec_name, public_name, public_name_len) == 0
- && subsec_name[public_name_len] == '_';
+ = ((strncmp (subsec_name, public_name, public_name_len) == 0
+ && subsec_name[public_name_len] == '_')
+ || (strncmp (subsec_name, "gnu_", 4) == 0
+ && strncmp (subsec_name + 4, "testing_", 8) != 0));
cursor += subsection_name_len;
op.read += subsection_name_len;
diff --git a/gas/config/obj-elf-attr.c b/gas/config/obj-elf-attr.c
index a309b45c4dd..208ef7cfab4 100644
--- a/gas/config/obj-elf-attr.c
+++ b/gas/config/obj-elf-attr.c
@@ -1272,4 +1272,38 @@ obj_elf_gnu_attribute (int ignored ATTRIBUTE_UNUSED)
obj_attr_process_attribute (OBJ_ATTR_GNU);
}
+#if (TC_OBJ_ATTR_v2)
+/* Return True if the VERSION of object attributes supports subsections, False
+ otherwise. */
+
+static inline bool
+attr_fmt_has_subsections (obj_attr_version_t version)
+{
+ switch (version)
+ {
+ case OBJ_ATTR_V1:
+ return false;
+ case OBJ_ATTR_V2:
+ return true;
+ default:
+ abort (); /* Unsupported format. */
+ }
+}
+
+/* Parse a .gnu_subsection directive. */
+
+void
+obj_elf_gnu_subsection (int ignored ATTRIBUTE_UNUSED)
+{
+ obj_attr_version_t version = elf_obj_attr_version (stdoutput);
+ if (! attr_fmt_has_subsections (version))
+ {
+ as_bad (_(".gnu_subsection is only available with object attributes v2"));
+ ignore_rest_of_line ();
+ return;
+ }
+ obj_attr_process_subsection ();
+}
+#endif /* TC_OBJ_ATTR_v2 */
+
#endif /* TC_OBJ_ATTR */
diff --git a/gas/config/obj-elf-attr.h b/gas/config/obj-elf-attr.h
index ba66daed826..a0bfe8e367d 100644
--- a/gas/config/obj-elf-attr.h
+++ b/gas/config/obj-elf-attr.h
@@ -50,6 +50,9 @@ extern void obj_attr_process_subsection (void);
#endif /* (TC_OBJ_ATTR_v2) */
extern void obj_elf_gnu_attribute (int);
+#if (TC_OBJ_ATTR_v2)
+extern void obj_elf_gnu_subsection (int);
+#endif /* TC_OBJ_ATTR_v2 */
#endif /* TC_OBJ_ATTR */
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index f82fcc43562..77e82e55d2f 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -117,6 +117,9 @@ static const pseudo_typeS elf_pseudo_table[] =
/* A GNU extension for object attributes. */
#ifdef TC_OBJ_ATTR
{"gnu_attribute", obj_elf_gnu_attribute, 0},
+#if TC_OBJ_ATTR_v2
+ {"gnu_subsection", obj_elf_gnu_subsection, 0},
+#endif /* TC_OBJ_ATTR_v2 */
#endif /* TC_OBJ_ATTR */
/* These are used for dwarf2. */
diff --git a/gas/doc/as.texi b/gas/doc/as.texi
index 5c5f499c85c..550cf9756d7 100644
--- a/gas/doc/as.texi
+++ b/gas/doc/as.texi
@@ -4597,6 +4597,7 @@ Some machine configurations provide additional directives.
* Func:: @code{.func}
* Global:: @code{.global @var{symbol}}, @code{.globl @var{symbol}}
@ifset ELF
+* Gnu_subsection:: @code{.gnu_subsection @var{name}, @var{comprehension}, @var{encoding}}
* Gnu_attribute:: @code{.gnu_attribute @var{tag},@var{value}}
* Hidden:: @code{.hidden @var{names}}
@end ifset
@@ -5744,9 +5745,48 @@ partial programs. You may need the HPPA-only @code{.EXPORT} directive as well.
@end ifset
@ifset ELF
+@node Gnu_subsection
+@section @code{.gnu_subsection @var{name}, @var{comprehension}, @var{encoding}}
+Create or switch the current object attributes subsection to @var{name} for This
+file. Valid values for @var{name} are following the pattern @code{[a-zA-Z0-9_]+}.
+
+The subsection property @var{comprehension} determines how a program processing
+the attributes handles attributes that it does not recognize (perhaps because
+the object file was generated by a different version of the toolchain). A
+subsection that is marked @code{optional} can be skipped if it is not
+understood. A subsection marked @code{required} implies that information
+conveyed by the attribute is required for correct processing of the object file;
+a fatal diagnostic must be generated if a tool does not recognize either the tag
+or the value associated with it.
+
+@var{encoding} specifies the expected encoding of the attributes recorded in the
+subsection. Currently supported values are @code{ULEB128}/@code{uleb128} and
+@code{NTBS}/@code{ntbs} (null-terminated byte string).
+
+On the first declaration of a subsection, both @var{comprehension} and
+@var{encoding} are mandatory parameters. However, on subsequent declarations,
+none of the parameters is required. If they are still specified, their values
+will be matched against the ones from the first declaration. Any mismatch will
+be reported as an error.
+
+This directive is only available for Object Attributes v2.
+
+@xref{Object Attributes}.
+
@node Gnu_attribute
@section @code{.gnu_attribute @var{tag},@var{value}}
-Record a @sc{gnu} object attribute for this file. @xref{Object Attributes}.
+
+For Object Attributes v1, record a @sc{gnu} object attribute with the pair
+@var{tag}, @var{value} for this file.
+
+For Object Attributes v2, record an object attribute with the pair @var{tag},
+@var{value} in the current subsection for this file.
+
+@var{tag} can either be an integer value, or a known named key. @var{value} can
+either be an integer or a string. For Object Attribute v2, the expected value
+type depends on the type set on the subsection.
+
+@xref{Object Attributes}.
@node Hidden
@section @code{.hidden @var{names}}
@@ -7953,32 +7993,61 @@ Many architectures support incompatible variations. For instance, floating
point arguments might be passed in floating point registers if the object file
requires hardware floating point support---or floating point arguments might be
passed in integer registers if the object file supports processors with no
-hardware floating point unit. Or, if two objects are built for different
-generations of the same architecture, the combination may require the
-newer generation at run-time.
-
-This information is useful during and after linking. At link time,
-@command{@value{LD}} can warn about incompatible object files. After link
-time, tools like @command{gdb} can use it to process the linked file
-correctly.
+hardware floating point unit. Another example might be when two object files
+make use of different architectural extensions: the final image will require
+both features to be supported at runtime; or if the features are mutually
+exclusive, the linker can issue a diagnostic.
-Compatibility information is recorded as a series of object attributes. Each
-attribute has a @dfn{vendor}, @dfn{tag}, and @dfn{value}. The vendor is a
-string, and indicates who sets the meaning of the tag. The tag is an integer,
-and indicates what property the attribute describes. The value may be a string
-or an integer, and indicates how the property affects this object. Missing
-attributes are the same as attributes with a zero value or empty string value.
+@command{@value{AS}} currently supports two versions of object attributes:
+@itemize @bullet{}
+@item
+Object Attributes version 1 (OAv1) used by: ARC, ARM, C-SKY, MIPS, MSP430, M68K,
+PowerPC, RISC-V, SPARC, s390, and TIC6X.
+@item
+Object Attributes version 2 (OAv2) used by: AArch64.
+@end itemize
-Object attributes were developed as part of the ABI for the ARM Architecture.
-The file format is documented in @cite{ELF for the ARM Architecture}.
+Object attributes are only supported when generating ELF format.
@menu
+* Object Attributes v1:: Object Attributes v1
+* Object Attributes v2:: Object Attributes v2
* GNU Object Attributes:: @sc{gnu} Object Attributes
* Defining New Object Attributes:: Defining New Object Attributes
@end menu
+@node Object Attributes v1
+@section Object Attributes v1
+
+In Object Attributes v1 (OAv1) Compatibility information is recorded as a series
+of object attributes. Each attribute has a @dfn{vendor}, @dfn{tag}, and
+@dfn{value}. The @dfn{vendor} is a string, and indicates who sets the meaning
+of the tag. The @dfn{tag} is an integer, and indicates what property the
+attribute describes. The @dfn{value} may be a string or an integer, and
+indicates how the property affects this object. Integer tags generally default
+to 0, while string tags default to the empty string. Tags are only recorded in
+the file if they have a non-default value.
+
+OAv1 were developed as part of the ABI for the ARM Architecture. The file
+format is documented in @cite{Addenda to, and Errata in, the ABI for the Arm
+Architecture}.
+
+@node Object Attributes v2
+@section Object Attributes v2
+
+Object Attributes v2 (OAv2) share common concepts of @dfn{vendor}, @dfn{tag}
+and @dfn{value} with OAv1, but also introduce the new ones like @dfn{subsection}
+and @dfn{scope}. Attributes with common properties are grouped into subsections.
+All the attributes in a subsection share the same encoding, comprehension, and
+scope. A subsection starting with the vendor name is considered public. The
+value of an attribute may be a string or an integer depending on the encoding
+set on its subsection.
+
+The file format used by OAv2 is documented in @cite{Build Attributes for the
+Arm 64-bit Architecture (AArch64)}, as AArch64 introduced it first.
+
@node GNU Object Attributes
-@section @sc{gnu} Object Attributes
+@section @sc{gnu} Object Attributes (OAv1 only)
The @code{.gnu_attribute} directive records an object attribute
with vendor @samp{gnu}.
--
2.52.0
- Previous message (by thread): [PATCH v11 21/25] ld tests for AArch64-specific merge coverage for AEABI Build Attributes
- Next message (by thread): [PATCH v11 23/25] gnu directives: gas/readelf tests for gnu attributes v2
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list