[PATCH v7 02/19] gas: move code for object attribute parsing into obj-elf-attr.c

Matthieu Longo matthieu.longo@arm.com
Mon Jul 14 17:18:37 GMT 2025


Adding backend maintainers in Cc.

On 2025-07-14 17:58, Matthieu Longo wrote:
> 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 | 237 ++++++++++++++++++++++++++++++++++++++
>   gas/config/obj-elf-attr.h |  35 ++++++
>   gas/config/obj-elf.c      | 224 ++---------------------------------
>   gas/config/obj-elf.h      |   5 +-
>   gas/config/tc-arc.h       |   5 +
>   gas/config/tc-arm.h       |   5 +
>   gas/config/tc-csky.h      |   5 +
>   gas/config/tc-m68k.h      |   5 +
>   gas/config/tc-mips.h      |   5 +
>   gas/config/tc-msp430.h    |   5 +
>   gas/config/tc-ppc.h       |   5 +
>   gas/config/tc-riscv.h     |   5 +
>   gas/config/tc-s390.h      |   5 +
>   gas/config/tc-sparc.h     |   5 +
>   gas/config/tc-tic6x.h     |   5 +
>   gas/configure             |  13 +++
>   gas/configure.ac          |  13 +++
>   gas/doc/as.texi           |   3 +-
>   gas/po/POTFILES.in        |   2 +
>   21 files changed, 377 insertions(+), 217 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..850db0e37fb
> --- /dev/null
> +++ b/gas/config/obj-elf-attr.c
> @@ -0,0 +1,237 @@
> +/* 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;
> +    }
> +  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 {
> +  struct recorded_attribute_info *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)
> +{
> +  while (node != NULL)
> +    {
> +      recorded_attribute_info_t *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.  */
> +  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..bc227c513ff
> --- /dev/null
> +++ b/gas/config/obj-elf-attr.h
> @@ -0,0 +1,35 @@
> +/* 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"
> +
> +#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 a5bb27847be..086dcba523c 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 },
> @@ -2050,218 +2054,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.  */
>   
> @@ -2271,6 +2064,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)
>   {
> @@ -3202,7 +2997,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
> @@ -3219,7 +3016,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..9e8a82f33de 100644
> --- a/gas/config/obj-elf.h
> +++ b/gas/config/obj-elf.h
> @@ -36,6 +36,7 @@
>   #include "bfd/elf-bfd.h"
>   
>   #include "targ-cpu.h"
> +#include "obj-elf-attr.h"
>   
>   #ifdef TC_ALPHA
>   #define ECOFF_DEBUGGING (alpha_flag_mdebug > 0)
> @@ -205,10 +206,6 @@ 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);
> -
>   /* 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.  */
>   #ifndef obj_sec_sym_ok_for_reloc
> diff --git a/gas/config/tc-arc.h b/gas/config/tc-arc.h
> index 65470f04483..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 4148a6fb634..5356a3ba9c0 100644
> --- a/gas/config/tc-arm.h
> +++ b/gas/config/tc-arm.h
> @@ -379,4 +379,9 @@ extern bool arm_tc_equal_in_insn (int, char *);
>   	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 d39108462a6..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 fc39a596d13..9aa9ed6f44c 100644
> --- a/gas/config/tc-msp430.h
> +++ b/gas/config/tc-msp430.h
> @@ -174,4 +174,9 @@ extern bool msp430_allow_local_subtract (expressionS *, expressionS *, segT);
>   
>   #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 e568c423c0a..e0a6328707a 100644
> --- a/gas/config/tc-ppc.h
> +++ b/gas/config/tc-ppc.h
> @@ -369,4 +369,9 @@ extern int ppc_dwarf2_line_min_insn_length;
>   #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 0c621253a6b..868e5b2e31b 100644
> --- a/gas/config/tc-s390.h
> +++ b/gas/config/tc-s390.h
> @@ -131,4 +131,9 @@ extern offsetT s390_sframe_cfa_ra_offset (void);
>   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 cfb89e009bc..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 58593331465..44b2b15aa0d 100644
> --- a/gas/config/tc-tic6x.h
> +++ b/gas/config/tc-tic6x.h
> @@ -228,4 +228,9 @@ 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 97340444b72..ec5ba8c08f5 100755
> --- a/gas/configure
> +++ b/gas/configure
> @@ -12349,6 +12349,19 @@ _ACEOF
>   	;;
>       esac
>   
> +    # Does the target support Object Attributes ?
> +    case ${cpu_type} in
> +      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 c65797fdf0a..c0116c7b79a 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
> +      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)
> diff --git a/gas/po/POTFILES.in b/gas/po/POTFILES.in
> index c600b179e43..c0ce266129e 100644
> --- a/gas/po/POTFILES.in
> +++ b/gas/po/POTFILES.in
> @@ -26,6 +26,8 @@ config/obj-coff.c
>   config/obj-coff.h
>   config/obj-ecoff.c
>   config/obj-ecoff.h
> +config/obj-elf-attr.c
> +config/obj-elf-attr.h
>   config/obj-elf.c
>   config/obj-elf.h
>   config/obj-evax.c



More information about the Binutils mailing list