]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gnu directives: add support for .gnu_attribute and .gnu_subsection in OAv2 context
authorMatthieu Longo <matthieu.longo@arm.com>
Thu, 17 Apr 2025 17:02:38 +0000 (18:02 +0100)
committerMatthieu Longo <matthieu.longo@arm.com>
Thu, 22 Jan 2026 10:11:17 +0000 (10:11 +0000)
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
binutils/readelf.c
gas/config/obj-elf-attr.c
gas/config/obj-elf-attr.h
gas/config/obj-elf.c
gas/doc/as.texi

index c012ba4956cc39309e278080dbf84a787728e975..904e097cf97603eb978f9955b2a90cda0b30a1dd 100644 (file)
@@ -605,8 +605,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;
 }
index 6d0c211fb1b644de80a8fbf9b49293e11c7d0e28..cca294c968c16c192055515eca7235f3f45b1b84 100644 (file)
@@ -20193,8 +20193,10 @@ elf_parse_attrs_subsection_v2 (const 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;
 
index c200d428606450b149c50710a78abdb15fabb622..1b91c11158cb0e6c07e2a4fdfe1328e0b1e5ab50 100644 (file)
@@ -1251,4 +1251,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 */
index 3c968fe683acfa6de7efe15a241c24e0d92e4a7d..1bda6b569998a4237de82405b24943a8271f2ad6 100644 (file)
@@ -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 */
 
index 47bf960d351bac35567692ae19fd3056ad8c8465..3c617bc36a3471545895e1c8ccbadebe28acb982 100644 (file)
@@ -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.  */
index 29c054376797e98b8d0cb2538db63abfaa77d34c..6114a178a0dea8465b361b626e59dd6a1dc551fc 100644 (file)
@@ -4603,6 +4603,7 @@ Some machine configurations provide additional directives.
 * Global::                      @code{.global @var{symbol}}, @code{.globl @var{symbol}}
 @ifset ELF
 * Gnu_attribute::               @code{.gnu_attribute @var{tag},@var{value}}
+* Gnu_subsection::              @code{.gnu_subsection @var{name}, @var{comprehension}, @var{encoding}}
 * Hidden::                      @code{.hidden @var{names}}
 @end ifset
 
@@ -5751,7 +5752,46 @@ partial programs.  You may need the HPPA-only @code{.EXPORT} directive as well.
 @ifset ELF
 @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 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 Hidden
 @section @code{.hidden @var{names}}
@@ -7958,32 +7998,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.
+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.
 
-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.
-
-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}.