[PATCH v6 02/19] gas: move code for object attribute parsing into obj-elf-attr.c
Matthieu Longo
matthieu.longo@arm.com
Fri Jul 11 11:28:47 GMT 2025
Gas, contrarilly to others binutils tools, is compiled for a specific
target. Some targets don't support Object Attributes (OAs). For those
cases, today the OA directive ".gnu_attribute" is still enabled but the
processing would probably fail in most of cases because the named tag
would be unknown. Most of the parsing code on such a target can be
considered as dead code.
This patch aims at removing this dead code from Gas when the target does
not support the OAs by:
- moving the code of OA parsing into a separate file under gas/config
which is only included for the relevant targets supporting OAs.
- disabling the code related to OAs on non-OA target via a TC_OBJ_ATTR
macro.
Adding/removing the OA feature from Gas for a specific target can easilly
be done from tc-<arch>.h by changing the values of TC_OBJ_ATTR: 1 enabled,
0 disabled. You might also want to guard the enablement of OAs only for
ELF targets with OBJ_ELF (see example below).
\#ifdef OBJ_ELF
/* The target supports Object Attributes. */
\#define TC_OBJ_ATTR 1
\#endif
---
gas/Makefile.am | 2 +
gas/Makefile.in | 5 +
gas/config/obj-elf-attr.c | 239 ++++++++++++++++++++++++++++++++++++++
gas/config/obj-elf-attr.h | 36 ++++++
gas/config/obj-elf.c | 224 ++---------------------------------
gas/config/obj-elf.h | 4 +-
gas/config/tc-arc.h | 5 +
gas/config/tc-arm.h | 8 ++
gas/config/tc-csky.h | 5 +
gas/config/tc-m68k.h | 5 +
gas/config/tc-mips.h | 5 +
gas/config/tc-msp430.h | 8 ++
gas/config/tc-ppc.h | 8 ++
gas/config/tc-riscv.h | 5 +
gas/config/tc-s390.h | 8 ++
gas/config/tc-sparc.h | 5 +
gas/config/tc-tic6x.h | 9 ++
gas/configure | 13 +++
gas/configure.ac | 13 +++
gas/doc/as.texi | 3 +-
20 files changed, 394 insertions(+), 216 deletions(-)
create mode 100644 gas/config/obj-elf-attr.c
create mode 100644 gas/config/obj-elf-attr.h
diff --git a/gas/Makefile.am b/gas/Makefile.am
index 5d0358ce345..f9b2e6891ab 100644
--- a/gas/Makefile.am
+++ b/gas/Makefile.am
@@ -291,6 +291,8 @@ TARGET_CPU_HFILES = \
TARGET_EXTRA_FILES = \
config/bfin-lex-wrapper.c \
+ config/obj-elf-attr.c \
+ config/obj-elf-attr.h \
config/xtensa-relax.c \
config/xtensa-relax.h \
config/kvx-parse.h \
diff --git a/gas/Makefile.in b/gas/Makefile.in
index 1f24d4a5bbc..741621206da 100644
--- a/gas/Makefile.in
+++ b/gas/Makefile.in
@@ -790,6 +790,8 @@ TARGET_CPU_HFILES = \
TARGET_EXTRA_FILES = \
config/bfin-lex-wrapper.c \
+ config/obj-elf-attr.c \
+ config/obj-elf-attr.h \
config/xtensa-relax.c \
config/xtensa-relax.h \
config/kvx-parse.h \
@@ -1244,6 +1246,8 @@ config/tc-z8k.$(OBJEXT): config/$(am__dirstamp) \
config/$(DEPDIR)/$(am__dirstamp)
config/bfin-lex-wrapper.$(OBJEXT): config/$(am__dirstamp) \
config/$(DEPDIR)/$(am__dirstamp)
+config/obj-elf-attr.$(OBJEXT): config/$(am__dirstamp) \
+ config/$(DEPDIR)/$(am__dirstamp)
config/xtensa-relax.$(OBJEXT): config/$(am__dirstamp) \
config/$(DEPDIR)/$(am__dirstamp)
config/kvx-parse.$(OBJEXT): config/$(am__dirstamp) \
@@ -1363,6 +1367,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/obj-aout.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/obj-coff.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/obj-ecoff.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/obj-elf-attr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/obj-elf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/obj-evax.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@config/$(DEPDIR)/obj-fdpicelf.Po@am__quote@
diff --git a/gas/config/obj-elf-attr.c b/gas/config/obj-elf-attr.c
new file mode 100644
index 00000000000..4bfbf973ea5
--- /dev/null
+++ b/gas/config/obj-elf-attr.c
@@ -0,0 +1,239 @@
+/* Object attributes parsing.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include "obj-elf-attr.h"
+
+#ifdef TC_OBJ_ATTR
+#include "safe-ctype.h"
+
+#define skip_whitespace(str) do { if (is_whitespace (*(str))) ++(str); } while (0)
+
+static inline bool
+skip_past_char (char ** str, char c)
+{
+ if (**str == c)
+ {
+ (*str)++;
+ return true;
+ }
+ else
+ return false;
+}
+#define skip_past_comma(str) skip_past_char (str, ',')
+
+/* A list of attributes that have been explicitly set by the assembly code.
+ VENDOR is the vendor id, BASE is the tag shifted right by the number
+ of bits in MASK, and bit N of MASK is set if tag BASE+N has been set. */
+typedef struct recorded_attribute_info_t {
+ struct recorded_attribute_info_t *next;
+ obj_attr_vendor_t vendor;
+ unsigned int base;
+ unsigned long mask;
+} recorded_attribute_info_t;
+static recorded_attribute_info_t *recorded_attributes;
+
+static void
+oav1_attr_info_free (recorded_attribute_info_t *node)
+{
+ recorded_attribute_info_t *next;
+ while (node != NULL)
+ {
+ next = node->next;
+ free (node);
+ node = next;
+ }
+}
+
+void
+oav1_attr_info_init ()
+{
+ /* Note: this "constructor" was added for symetry with oav1_attr_info_exit.
+ recorded_attributes is a static variable which is automatically initialized
+ to NULL. There is no need to initialize it another time except for a
+ cosmetic reason. */
+ recorded_attributes = NULL;
+}
+
+void
+oav1_attr_info_exit ()
+{
+ oav1_attr_info_free (recorded_attributes);
+}
+
+/* Record that we have seen an explicit specification of attribute TAG
+ for vendor VENDOR. */
+
+static void
+oav1_attr_record_seen (obj_attr_vendor_t vendor, obj_attr_tag_t tag)
+{
+ unsigned int base;
+ unsigned long mask;
+ recorded_attribute_info_t *rai;
+
+ base = tag / (8 * sizeof (rai->mask));
+ mask = 1UL << (tag % (8 * sizeof (rai->mask)));
+ for (rai = recorded_attributes; rai; rai = rai->next)
+ if (rai->vendor == vendor && rai->base == base)
+ {
+ rai->mask |= mask;
+ return;
+ }
+
+ rai = XNEW (recorded_attribute_info_t);
+ rai->next = recorded_attributes;
+ rai->vendor = vendor;
+ rai->base = base;
+ rai->mask = mask;
+ recorded_attributes = rai;
+}
+
+/* Return true if we have seen an explicit specification of attribute TAG
+ for vendor VENDOR. */
+
+bool
+oav1_attr_seen (obj_attr_vendor_t vendor, obj_attr_tag_t tag)
+{
+ unsigned int base;
+ unsigned long mask;
+ recorded_attribute_info_t *rai;
+
+ base = tag / (8 * sizeof (rai->mask));
+ mask = 1UL << (tag % (8 * sizeof (rai->mask)));
+ for (rai = recorded_attributes; rai; rai = rai->next)
+ if (rai->vendor == vendor && rai->base == base)
+ return (rai->mask & mask) != 0;
+ return false;
+}
+
+/* Parse an attribute directive for VENDOR.
+ Returns the attribute number read, or zero on error. */
+
+obj_attr_tag_t
+obj_attr_v1_process_attribute (obj_attr_vendor_t vendor)
+{
+ expressionS exp;
+ int type;
+ int tag;
+ unsigned int i = 0;
+ char *s = NULL;
+
+ /* Read the first number or name. */
+ skip_whitespace (input_line_pointer);
+ s = input_line_pointer;
+ if (ISDIGIT (*input_line_pointer))
+ {
+ expression (& exp);
+ if (exp.X_op != O_constant)
+ goto bad;
+ tag = exp.X_add_number;
+ }
+ else
+ {
+ char *name;
+
+ /* A name may contain '_', but no other punctuation. */
+ for (; ISALNUM (*input_line_pointer) || *input_line_pointer == '_';
+ ++input_line_pointer)
+ i++;
+ if (i == 0)
+ goto bad;
+
+ name = xmemdup0 (s, i);
+
+#ifndef CONVERT_SYMBOLIC_ATTRIBUTE
+#define CONVERT_SYMBOLIC_ATTRIBUTE(a) -1
+#endif
+
+ tag = CONVERT_SYMBOLIC_ATTRIBUTE (name);
+ if (tag == -1)
+ {
+ as_bad (_("Attribute name not recognised: %s"), name);
+ ignore_rest_of_line ();
+ free (name);
+ return 0;
+ }
+ free (name);
+ }
+
+ type = _bfd_elf_obj_attrs_arg_type (stdoutput, vendor, tag);
+
+ if (! skip_past_comma (&input_line_pointer))
+ goto bad;
+ if (type & 1)
+ {
+ expression (& exp);
+ if (exp.X_op != O_constant)
+ {
+ as_bad (_("expected numeric constant"));
+ ignore_rest_of_line ();
+ return 0;
+ }
+ i = exp.X_add_number;
+ }
+ if ((type & 3) == 3
+ && ! skip_past_comma (&input_line_pointer))
+ {
+ as_bad (_("expected comma"));
+ ignore_rest_of_line ();
+ return 0;
+ }
+ if (type & 2)
+ {
+ int len;
+
+ skip_whitespace (input_line_pointer);
+ if (*input_line_pointer != '"')
+ goto bad_string;
+ s = demand_copy_C_string (&len);
+ }
+
+ oav1_attr_record_seen (vendor, tag);
+ bool ok = false;
+ switch (type & 3)
+ {
+ case 3:
+ ok = bfd_elf_add_obj_attr_int_string (stdoutput, vendor, tag, i, s);
+ break;
+ case 2:
+ ok = bfd_elf_add_obj_attr_string (stdoutput, vendor, tag, s);
+ break;
+ case 1:
+ ok = bfd_elf_add_obj_attr_int (stdoutput, vendor, tag, i);
+ break;
+ default:
+ abort ();
+ }
+ if (!ok)
+ as_fatal (_("error adding attribute: %s"),
+ bfd_errmsg (bfd_get_error ()));
+
+ demand_empty_rest_of_line ();
+ return tag;
+ bad_string:
+ as_bad (_("bad string constant"));
+ ignore_rest_of_line ();
+ return 0;
+ bad:
+ as_bad (_("expected <tag> , <value>"));
+ ignore_rest_of_line ();
+ return 0;
+}
+
+#endif /* TC_OBJ_ATTR */
diff --git a/gas/config/obj-elf-attr.h b/gas/config/obj-elf-attr.h
new file mode 100644
index 00000000000..f5e070103cf
--- /dev/null
+++ b/gas/config/obj-elf-attr.h
@@ -0,0 +1,36 @@
+/* Object attributes parsing.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS 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, or (at your option)
+ any later version.
+
+ GAS 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 GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#ifndef _OBJ_ELF_ATTR_H
+#define _OBJ_ELF_ATTR_H
+
+#include "as.h"
+#include "bfd/elf-bfd.h"
+
+#ifdef TC_OBJ_ATTR
+
+extern void oav1_attr_info_init (void);
+extern void oav1_attr_info_exit (void);
+extern bool oav1_attr_seen (obj_attr_vendor_t, obj_attr_tag_t);
+extern obj_attr_tag_t obj_attr_v1_process_attribute (obj_attr_vendor_t);
+
+#endif /* TC_OBJ_ATTR */
+
+#endif /* _OBJ_ELF_ATTR_H */
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index 2f74a7e599d..a5ff4484b04 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -71,7 +71,9 @@ static void obj_elf_visibility (int);
static void obj_elf_symver (int);
static void obj_elf_subsection (int);
static void obj_elf_popsection (int);
+#ifdef TC_OBJ_ATTR
static void obj_elf_gnu_attribute (int);
+#endif /* TC_OBJ_ATTR */
static void obj_elf_tls_common (int);
static void obj_elf_lcomm (int);
static void obj_elf_struct (int);
@@ -116,7 +118,9 @@ static const pseudo_typeS elf_pseudo_table[] =
{"vtable_entry", obj_elf_vtable_entry, 0},
/* A GNU extension for object attributes. */
+#ifdef TC_OBJ_ATTR
{"gnu_attribute", obj_elf_gnu_attribute, 0},
+#endif /* TC_OBJ_ATTR */
/* These are used for dwarf2. */
{ "file", dwarf2_directive_file, 0 },
@@ -2041,218 +2045,7 @@ obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED)
(void) obj_elf_get_vtable_entry ();
}
-#define skip_whitespace(str) do { if (is_whitespace (*(str))) ++(str); } while (0)
-
-static inline int
-skip_past_char (char ** str, char c)
-{
- if (**str == c)
- {
- (*str)++;
- return 0;
- }
- else
- return -1;
-}
-#define skip_past_comma(str) skip_past_char (str, ',')
-
-/* A list of attributes that have been explicitly set by the assembly code.
- VENDOR is the vendor id, BASE is the tag shifted right by the number
- of bits in MASK, and bit N of MASK is set if tag BASE+N has been set. */
-typedef struct recorded_attribute_info_t {
- struct recorded_attribute_info_t *next;
- obj_attr_vendor_t vendor;
- unsigned int base;
- unsigned long mask;
-} recorded_attribute_info_t;
-static recorded_attribute_info_t *recorded_attributes;
-
-static void
-oav1_attr_info_free (recorded_attribute_info_t *node)
-{
- recorded_attribute_info_t *next;
- while (node != NULL)
- {
- next = node->next;
- free (node);
- node = next;
- }
-}
-
-static void
-oav1_attr_info_init (void)
-{
- /* Note: this "constructor" was added for symetry with oav1_attr_info_exit.
- recorded_attributes is a static variable which is automatically initialized
- to NULL. There is no need to initialize it another time except for a
- cosmetic reason. */
- recorded_attributes = NULL;
-}
-
-static void
-oav1_attr_info_exit (void)
-{
- oav1_attr_info_free (recorded_attributes);
-}
-
-/* Record that we have seen an explicit specification of attribute TAG
- for vendor VENDOR. */
-
-static void
-oav1_attr_record_seen (obj_attr_vendor_t vendor, obj_attr_tag_t tag)
-{
- unsigned int base;
- unsigned long mask;
- recorded_attribute_info_t *rai;
-
- base = tag / (8 * sizeof (rai->mask));
- mask = 1UL << (tag % (8 * sizeof (rai->mask)));
- for (rai = recorded_attributes; rai; rai = rai->next)
- if (rai->vendor == vendor && rai->base == base)
- {
- rai->mask |= mask;
- return;
- }
-
- rai = XNEW (recorded_attribute_info_t);
- rai->next = recorded_attributes;
- rai->vendor = vendor;
- rai->base = base;
- rai->mask = mask;
- recorded_attributes = rai;
-}
-
-/* Return true if we have seen an explicit specification of attribute TAG
- for vendor VENDOR. */
-
-bool
-oav1_attr_seen (obj_attr_vendor_t vendor, obj_attr_tag_t tag)
-{
- unsigned int base;
- unsigned long mask;
- recorded_attribute_info_t *rai;
-
- base = tag / (8 * sizeof (rai->mask));
- mask = 1UL << (tag % (8 * sizeof (rai->mask)));
- for (rai = recorded_attributes; rai; rai = rai->next)
- if (rai->vendor == vendor && rai->base == base)
- return (rai->mask & mask) != 0;
- return false;
-}
-
-/* Parse an attribute directive for VENDOR.
- Returns the attribute number read, or zero on error. */
-
-obj_attr_tag_t
-obj_attr_v1_process_attribute (obj_attr_vendor_t vendor)
-{
- expressionS exp;
- int type;
- int tag;
- unsigned int i = 0;
- char *s = NULL;
-
- /* Read the first number or name. */
- skip_whitespace (input_line_pointer);
- s = input_line_pointer;
- if (ISDIGIT (*input_line_pointer))
- {
- expression (& exp);
- if (exp.X_op != O_constant)
- goto bad;
- tag = exp.X_add_number;
- }
- else
- {
- char *name;
-
- /* A name may contain '_', but no other punctuation. */
- for (; ISALNUM (*input_line_pointer) || *input_line_pointer == '_';
- ++input_line_pointer)
- i++;
- if (i == 0)
- goto bad;
-
- name = xmemdup0 (s, i);
-
-#ifndef CONVERT_SYMBOLIC_ATTRIBUTE
-#define CONVERT_SYMBOLIC_ATTRIBUTE(a) -1
-#endif
-
- tag = CONVERT_SYMBOLIC_ATTRIBUTE (name);
- if (tag == -1)
- {
- as_bad (_("Attribute name not recognised: %s"), name);
- ignore_rest_of_line ();
- free (name);
- return 0;
- }
- free (name);
- }
-
- type = _bfd_elf_obj_attrs_arg_type (stdoutput, vendor, tag);
-
- if (skip_past_comma (&input_line_pointer) == -1)
- goto bad;
- if (type & 1)
- {
- expression (& exp);
- if (exp.X_op != O_constant)
- {
- as_bad (_("expected numeric constant"));
- ignore_rest_of_line ();
- return 0;
- }
- i = exp.X_add_number;
- }
- if ((type & 3) == 3
- && skip_past_comma (&input_line_pointer) == -1)
- {
- as_bad (_("expected comma"));
- ignore_rest_of_line ();
- return 0;
- }
- if (type & 2)
- {
- int len;
-
- skip_whitespace (input_line_pointer);
- if (*input_line_pointer != '"')
- goto bad_string;
- s = demand_copy_C_string (&len);
- }
-
- oav1_attr_record_seen (vendor, tag);
- bool ok = false;
- switch (type & 3)
- {
- case 3:
- ok = bfd_elf_add_obj_attr_int_string (stdoutput, vendor, tag, i, s);
- break;
- case 2:
- ok = bfd_elf_add_obj_attr_string (stdoutput, vendor, tag, s);
- break;
- case 1:
- ok = bfd_elf_add_obj_attr_int (stdoutput, vendor, tag, i);
- break;
- default:
- abort ();
- }
- if (!ok)
- as_fatal (_("error adding attribute: %s"),
- bfd_errmsg (bfd_get_error ()));
-
- demand_empty_rest_of_line ();
- return tag;
- bad_string:
- as_bad (_("bad string constant"));
- ignore_rest_of_line ();
- return 0;
- bad:
- as_bad (_("expected <tag> , <value>"));
- ignore_rest_of_line ();
- return 0;
-}
+#ifdef TC_OBJ_ATTR
/* Parse a .gnu_attribute directive. */
@@ -2262,6 +2055,8 @@ obj_elf_gnu_attribute (int ignored ATTRIBUTE_UNUSED)
obj_attr_v1_process_attribute (OBJ_ATTR_GNU);
}
+#endif /* TC_OBJ_ATTR */
+
void
elf_obj_read_begin_hook (void)
{
@@ -3193,7 +2988,9 @@ elf_begin (void)
comment_section = NULL;
memset (&groups, 0, sizeof (groups));
+#ifdef TC_OBJ_ATTR
oav1_attr_info_init ();
+#endif /* TC_OBJ_ATTR */
}
void
@@ -3210,7 +3007,10 @@ elf_end (void)
htab_delete (groups.indexes);
free (groups.head);
}
+
+#ifdef TC_OBJ_ATTR
oav1_attr_info_exit ();
+#endif /* TC_OBJ_ATTR */
}
#ifdef USE_EMULATIONS
diff --git a/gas/config/obj-elf.h b/gas/config/obj-elf.h
index 637243f9ffd..913921bfead 100644
--- a/gas/config/obj-elf.h
+++ b/gas/config/obj-elf.h
@@ -205,9 +205,7 @@ extern void obj_elf_vtable_entry (int);
extern struct fix * obj_elf_get_vtable_inherit (void);
extern struct fix * obj_elf_get_vtable_entry (void);
-/* Object attributes v1. */
-extern bool oav1_attr_seen (obj_attr_vendor_t, obj_attr_tag_t);
-extern obj_attr_tag_t obj_attr_v1_process_attribute (obj_attr_vendor_t);
+#include "obj-elf-attr.h"
/* BFD wants to write the udata field, which is a no-no for the
predefined section symbols in bfd/section.c. They are read-only. */
diff --git a/gas/config/tc-arc.h b/gas/config/tc-arc.h
index 145d955a4e2..e382ee5a411 100644
--- a/gas/config/tc-arc.h
+++ b/gas/config/tc-arc.h
@@ -271,4 +271,9 @@ struct arc_relax_type
extern void arc_md_end (void);
#define md_end arc_md_end
+#ifdef OBJ_ELF
+/* The target supports Object Attributes. */
+#define TC_OBJ_ATTR 1
#endif
+
+#endif /* TC_ARC */
diff --git a/gas/config/tc-arm.h b/gas/config/tc-arm.h
index aa5f1175df1..5356a3ba9c0 100644
--- a/gas/config/tc-arm.h
+++ b/gas/config/tc-arm.h
@@ -20,6 +20,7 @@
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
+#ifndef TC_ARM
#define TC_ARM 1
#ifndef TARGET_BYTES_BIG_ENDIAN
@@ -377,3 +378,10 @@ extern bool arm_tc_equal_in_insn (int, char *);
#define TC_LARGEST_EXPONENT_IS_NORMAL(PRECISION) \
arm_is_largest_exponent_ok ((PRECISION))
int arm_is_largest_exponent_ok (int precision);
+
+#ifdef OBJ_ELF
+/* The target supports Object Attributes. */
+#define TC_OBJ_ATTR 1
+#endif
+
+#endif /* TC_ARM */
diff --git a/gas/config/tc-csky.h b/gas/config/tc-csky.h
index 7e323473e0f..0f6995cbc9d 100644
--- a/gas/config/tc-csky.h
+++ b/gas/config/tc-csky.h
@@ -106,4 +106,9 @@ extern long csky_relax_frag (segT, fragS *, long);
const char * elf32_csky_target_format (void);
#endif
+#ifdef OBJ_ELF
+/* The target supports Object Attributes. */
+#define TC_OBJ_ATTR 1
#endif
+
+#endif /* TC_CSKY */
diff --git a/gas/config/tc-m68k.h b/gas/config/tc-m68k.h
index 0314a00c2d4..f6b75cbb002 100644
--- a/gas/config/tc-m68k.h
+++ b/gas/config/tc-m68k.h
@@ -155,4 +155,9 @@ struct m68k_tc_sy
#define TC_SYMFIELD_TYPE struct m68k_tc_sy
+#ifdef OBJ_ELF
+/* The target supports Object Attributes. */
+#define TC_OBJ_ATTR 1
+#endif
+
#endif /* TC_M68K_H */
diff --git a/gas/config/tc-mips.h b/gas/config/tc-mips.h
index dff86c6c712..43cc01228b6 100644
--- a/gas/config/tc-mips.h
+++ b/gas/config/tc-mips.h
@@ -217,4 +217,9 @@ extern bfd_reloc_code_real_type mips_cfi_reloc_for_encoding (int encoding);
#define CONVERT_SYMBOLIC_ATTRIBUTE(name) mips_convert_symbolic_attribute (name)
extern int mips_convert_symbolic_attribute (const char *);
+#ifdef OBJ_ELF
+/* The target supports Object Attributes. */
+#define TC_OBJ_ATTR 1
+#endif
+
#endif /* TC_MIPS */
diff --git a/gas/config/tc-msp430.h b/gas/config/tc-msp430.h
index 47da4aac407..9aa9ed6f44c 100644
--- a/gas/config/tc-msp430.h
+++ b/gas/config/tc-msp430.h
@@ -20,6 +20,7 @@
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
+#ifndef TC_MSP430
#define TC_MSP430
/* By convention, you should define this macro in the `.h' file. For
example, `tc-m68k.h' defines `TC_M68K'. You might have to use this
@@ -172,3 +173,10 @@ extern bool msp430_allow_local_subtract (expressionS *, expressionS *, segT);
#define TC_LINKRELAX_FIXUP(seg) ((seg->flags & SEC_CODE) || (seg->flags & SEC_DEBUGGING))
#define DWARF2_ADDR_SIZE(bfd) 4
+
+#ifdef OBJ_ELF
+/* The target supports Object Attributes. */
+#define TC_OBJ_ATTR 1
+#endif
+
+#endif /* TC_MSP430 */
diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h
index 97e2f4ed197..e0a6328707a 100644
--- a/gas/config/tc-ppc.h
+++ b/gas/config/tc-ppc.h
@@ -19,6 +19,7 @@
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
+#ifndef TC_PPC
#define TC_PPC
#include "opcode/ppc.h"
@@ -367,3 +368,10 @@ extern int ppc_dwarf2_line_min_insn_length;
#define DWARF2_DEFAULT_RETURN_COLUMN 0x41
#define DWARF2_CIE_DATA_ALIGNMENT ppc_cie_data_alignment
#define EH_FRAME_ALIGNMENT 2
+
+#ifdef OBJ_ELF
+/* The target supports Object Attributes. */
+#define TC_OBJ_ATTR 1
+#endif
+
+#endif /* TC_PPC */
diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
index 853f34967fa..389a9f42c13 100644
--- a/gas/config/tc-riscv.h
+++ b/gas/config/tc-riscv.h
@@ -187,4 +187,9 @@ extern void riscv_adjust_symtab (void);
#define OBJ_COPY_SYMBOL_ATTRIBUTES(DEST, SRC) \
elf_copy_symbol_size (DEST, SRC)
+#ifdef OBJ_ELF
+/* The target supports Object Attributes. */
+#define TC_OBJ_ATTR 1
+#endif
+
#endif /* TC_RISCV */
diff --git a/gas/config/tc-s390.h b/gas/config/tc-s390.h
index c92769e507b..868e5b2e31b 100644
--- a/gas/config/tc-s390.h
+++ b/gas/config/tc-s390.h
@@ -19,6 +19,7 @@
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
+#ifndef TC_S390
#define TC_S390
struct fix;
@@ -129,3 +130,10 @@ extern offsetT s390_sframe_cfa_ra_offset (void);
/* The abi/arch identifier for SFrame. */
unsigned char s390_sframe_get_abi_arch (void);
#define sframe_get_abi_arch s390_sframe_get_abi_arch
+
+#ifdef OBJ_ELF
+/* The target supports Object Attributes. */
+#define TC_OBJ_ATTR 1
+#endif
+
+#endif /* TC_S390 */
diff --git a/gas/config/tc-sparc.h b/gas/config/tc-sparc.h
index d569fe7f2b6..ff517adfd53 100644
--- a/gas/config/tc-sparc.h
+++ b/gas/config/tc-sparc.h
@@ -178,4 +178,9 @@ extern int sparc_cie_data_alignment;
this, BFD_RELOC_32_PCREL will be emitted directly instead. */
#define CFI_DIFF_EXPR_OK 0
+#ifdef OBJ_ELF
+/* The target supports Object Attributes. */
+#define TC_OBJ_ATTR 1
#endif
+
+#endif /* TC_SPARC */
diff --git a/gas/config/tc-tic6x.h b/gas/config/tc-tic6x.h
index 55f2b2c8580..44b2b15aa0d 100644
--- a/gas/config/tc-tic6x.h
+++ b/gas/config/tc-tic6x.h
@@ -18,7 +18,9 @@
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
+#ifndef TC_TIC6X
#define TC_TIC6X 1
+
#define TARGET_BYTES_BIG_ENDIAN 0
#define WORKING_DOT_WORD
#define DOUBLEBAR_PARALLEL
@@ -225,3 +227,10 @@ struct fde_entry;
void tic6x_cfi_endproc (struct fde_entry *fde);
#define tc_cfi_section_name ".c6xabi.exidx"
+
+#ifdef OBJ_ELF
+/* The target supports Object Attributes. */
+#define TC_OBJ_ATTR 1
+#endif
+
+#endif /* TC_TIC6X */
diff --git a/gas/configure b/gas/configure
index 3212e5f06d0..d1c0fee9c36 100755
--- a/gas/configure
+++ b/gas/configure
@@ -12349,6 +12349,19 @@ _ACEOF
;;
esac
+ # Does the target support Object Attributes ?
+ case ${cpu_type} in
+ aarch64* | arc* | arm* | csky | m68k | mips* | msp430 | powerpc* \
+ | riscv* | s390* | sparc* | tic6x)
+ for f in config/obj-elf-attr.o; do
+ case " $extra_objects " in
+ *" $f "*) ;;
+ *) extra_objects="$extra_objects $f" ;;
+ esac
+ done
+ ;;
+ esac
+
# Any other special object files needed ?
case ${cpu_type} in
diff --git a/gas/configure.ac b/gas/configure.ac
index 30fa5eb13ea..0dc3de51c20 100644
--- a/gas/configure.ac
+++ b/gas/configure.ac
@@ -454,6 +454,19 @@ changequote([,])dnl
;;
esac
+ # Does the target support Object Attributes ?
+ case ${cpu_type} in
+ aarch64* | arc* | arm* | csky | m68k | mips* | msp430 | powerpc* \
+ | riscv* | s390* | sparc* | tic6x)
+ for f in config/obj-elf-attr.o; do
+ case " $extra_objects " in
+ *" $f "*) ;;
+ *) extra_objects="$extra_objects $f" ;;
+ esac
+ done
+ ;;
+ esac
+
# Any other special object files needed ?
case ${cpu_type} in
diff --git a/gas/doc/as.texi b/gas/doc/as.texi
index 70c25405f87..c2e33b26398 100644
--- a/gas/doc/as.texi
+++ b/gas/doc/as.texi
@@ -7985,7 +7985,8 @@ architecture-dependent ones.
@subsection Common @sc{gnu} attributes
-These attributes are valid on all architectures.
+The following attribute is supported on all targets that support
+processor-specific attribute tags as described below.
@table @r
@item Tag_compatibility (32)
--
2.50.1
More information about the Binutils
mailing list