From: Matthieu Longo Date: Mon, 14 Jul 2025 14:19:05 +0000 (+0100) Subject: gas: move code for object attribute parsing into obj-elf-attr.c X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=28a51085ae59fdb530fbdce1e2a7d160667e3007;p=thirdparty%2Fbinutils-gdb.git gas: move code for object attribute parsing into obj-elf-attr.c 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-.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 --- 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 76e633d5298..babe9a6d000 100644 --- a/gas/Makefile.in +++ b/gas/Makefile.in @@ -793,6 +793,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 \ @@ -1247,6 +1249,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) \ @@ -1366,6 +1370,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..3bb2b70d386 --- /dev/null +++ b/gas/config/obj-elf-attr.c @@ -0,0 +1,246 @@ +/* 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 symmetry 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 and to possibly help fuzzing. */ + 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 , ")); + ignore_rest_of_line (); + return 0; +} + +/* Parse a .gnu_attribute directive. */ + +void +obj_elf_gnu_attribute (int ignored ATTRIBUTE_UNUSED) +{ + obj_attr_v1_process_attribute (OBJ_ATTR_GNU); +} + +#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..42e8af886ba --- /dev/null +++ b/gas/config/obj-elf-attr.h @@ -0,0 +1,37 @@ +/* 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); + +extern void obj_elf_gnu_attribute (int); + +#endif /* TC_OBJ_ATTR */ + +#endif /* _OBJ_ELF_ATTR_H */ diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c index 3b3bb645f3b..bf823c8745f 100644 --- a/gas/config/obj-elf.c +++ b/gas/config/obj-elf.c @@ -71,7 +71,6 @@ static void obj_elf_visibility (int); static void obj_elf_symver (int); static void obj_elf_subsection (int); static void obj_elf_popsection (int); -static void obj_elf_gnu_attribute (int); static void obj_elf_tls_common (int); static void obj_elf_lcomm (int); static void obj_elf_struct (int); @@ -116,7 +115,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 }, @@ -2072,226 +2073,6 @@ 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 { - 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; - } -} - -static void -oav1_attr_info_init (void) -{ - /* Note: this "constructor" was added for symmetry 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 and to possibly help fuzzing. */ - 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 , ")); - ignore_rest_of_line (); - return 0; -} - -/* Parse a .gnu_attribute directive. */ - -static void -obj_elf_gnu_attribute (int ignored ATTRIBUTE_UNUSED) -{ - obj_attr_v1_process_attribute (OBJ_ATTR_GNU); -} - void elf_obj_read_begin_hook (void) { @@ -3223,7 +3004,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 @@ -3240,7 +3023,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..0ab2eb95cad 100644 --- a/gas/config/tc-arc.h +++ b/gas/config/tc-arc.h @@ -271,4 +271,7 @@ struct arc_relax_type extern void arc_md_end (void); #define md_end arc_md_end +/* The target supports Object Attributes. */ +#define TC_OBJ_ATTR 1 + #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..3724f436b61 100644 --- a/gas/config/tc-csky.h +++ b/gas/config/tc-csky.h @@ -106,4 +106,7 @@ extern long csky_relax_frag (segT, fragS *, long); const char * elf32_csky_target_format (void); #endif +/* The target supports Object Attributes. */ +#define TC_OBJ_ATTR 1 + #endif /* TC_CSKY */ diff --git a/gas/config/tc-m68k.h b/gas/config/tc-m68k.h index 0314a00c2d4..7ab701489f3 100644 --- a/gas/config/tc-m68k.h +++ b/gas/config/tc-m68k.h @@ -155,4 +155,7 @@ struct m68k_tc_sy #define TC_SYMFIELD_TYPE struct m68k_tc_sy +/* The target supports Object Attributes. */ +#define TC_OBJ_ATTR 1 + #endif /* TC_M68K_H */ diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 9c59ebba0b6..42cbd7702e2 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -20911,7 +20911,7 @@ mips_md_finish (void) file_mips_check_options (); /* Set a floating-point ABI if the user did not. */ - if (obj_attr_v1_rai_seen (OBJ_ATTR_GNU, Tag_GNU_MIPS_ABI_FP)) + if (oav1_attr_seen (OBJ_ATTR_GNU, Tag_GNU_MIPS_ABI_FP)) { /* Perform consistency checks on the floating-point ABI. */ fpabi = bfd_elf_get_obj_attr_int (stdoutput, OBJ_ATTR_GNU, diff --git a/gas/config/tc-mips.h b/gas/config/tc-mips.h index dff86c6c712..423229a7e25 100644 --- a/gas/config/tc-mips.h +++ b/gas/config/tc-mips.h @@ -217,4 +217,7 @@ 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 *); +/* The target supports Object Attributes. */ +#define TC_OBJ_ATTR 1 + #endif /* TC_MIPS */ diff --git a/gas/config/tc-msp430.h b/gas/config/tc-msp430.h index fc39a596d13..73d435b1c1e 100644 --- a/gas/config/tc-msp430.h +++ b/gas/config/tc-msp430.h @@ -174,4 +174,7 @@ extern bool msp430_allow_local_subtract (expressionS *, expressionS *, segT); #define DWARF2_ADDR_SIZE(bfd) 4 +/* The target supports Object Attributes. */ +#define TC_OBJ_ATTR 1 + #endif /* TC_MSP430 */ diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h index 3bbeafc172c..5bb8b8b7d1e 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..2348ec33640 100644 --- a/gas/config/tc-riscv.h +++ b/gas/config/tc-riscv.h @@ -187,4 +187,7 @@ extern void riscv_adjust_symtab (void); #define OBJ_COPY_SYMBOL_ATTRIBUTES(DEST, SRC) \ elf_copy_symbol_size (DEST, SRC) +/* The target supports Object Attributes. */ +#define TC_OBJ_ATTR 1 + #endif /* TC_RISCV */ diff --git a/gas/config/tc-s390.h b/gas/config/tc-s390.h index 0c621253a6b..32f1dde94af 100644 --- a/gas/config/tc-s390.h +++ b/gas/config/tc-s390.h @@ -131,4 +131,7 @@ 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 +/* The target supports Object Attributes. */ +#define TC_OBJ_ATTR 1 + #endif /* TC_S390 */ diff --git a/gas/config/tc-sparc.h b/gas/config/tc-sparc.h index cfb89e009bc..08acfccd89b 100644 --- a/gas/config/tc-sparc.h +++ b/gas/config/tc-sparc.h @@ -178,4 +178,7 @@ extern int sparc_cie_data_alignment; this, BFD_RELOC_32_PCREL will be emitted directly instead. */ #define CFI_DIFF_EXPR_OK 0 +/* The target supports Object Attributes. */ +#define TC_OBJ_ATTR 1 + #endif /* TC_SPARC */ diff --git a/gas/config/tc-tic6x.h b/gas/config/tc-tic6x.h index 58593331465..08f9715eaf5 100644 --- a/gas/config/tc-tic6x.h +++ b/gas/config/tc-tic6x.h @@ -228,4 +228,7 @@ void tic6x_cfi_endproc (struct fde_entry *fde); #define tc_cfi_section_name ".c6xabi.exidx" +/* The target supports Object Attributes. */ +#define TC_OBJ_ATTR 1 + #endif /* TC_TIC6X */ diff --git a/gas/configure b/gas/configure index 33d199db363..52bbfdc3e81 100755 --- a/gas/configure +++ b/gas/configure @@ -12699,6 +12699,19 @@ _ACEOF ;; esac + # Does the target support Object Attributes ? + case ${cpu_type} in + arc* | arm* | csky | m68k | mips* | msp430 | ppc* \ + | 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 61ed65fcf8b..f176578870d 100644 --- a/gas/configure.ac +++ b/gas/configure.ac @@ -432,6 +432,19 @@ changequote([,])dnl ;; esac + # Does the target support Object Attributes ? + case ${cpu_type} in + arc* | arm* | csky | m68k | mips* | msp430 | ppc* \ + | 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 9b8fb4b5104..5c5f499c85c 100644 --- a/gas/doc/as.texi +++ b/gas/doc/as.texi @@ -7991,7 +7991,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