From: Matthieu Longo Date: Thu, 17 Apr 2025 14:02:18 +0000 (+0100) Subject: gas: use common code for object attribute v1 & v2 parsing X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f860cea7c69ffa3de1471f7dbb6efc8f9715db4c;p=thirdparty%2Fbinutils-gdb.git gas: use common code for object attribute v1 & v2 parsing Since the previous patch added all the code to be able to parse both OAv1 and OAv2 directives, this patch switches OAv1 to use this common code. Additionally to the common code in obj-elf.c, the following backends using a custom object attribute directive were impacted. - ARC - Arm - m68k - PowerPC - RISC-V - TI C6X A parsing test for Arm had to be adapted to the error messages of the new parser. The gas and ld test suites were successfully run for the following backends: S390, ARC, Arm, CSky, m68k, msp430, PowerPC, TI C6X, RISC-V, AArch64, MIPS, SPARC. --- diff --git a/gas/config/obj-elf-attr.c b/gas/config/obj-elf-attr.c index 505390002f0..c200d428606 100644 --- a/gas/config/obj-elf-attr.c +++ b/gas/config/obj-elf-attr.c @@ -1243,132 +1243,12 @@ obj_attr_process_subsection (void) } #endif /* TC_OBJ_ATTR_v2 */ -#if (TC_OBJ_ATTR_v1) -/* 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; -} -#endif /* TC_OBJ_ATTR_v1 */ - /* Parse a .gnu_attribute directive. */ void obj_elf_gnu_attribute (int ignored ATTRIBUTE_UNUSED) { -#if (TC_OBJ_ATTR_v1 && !TC_OBJ_ATTR_v2) - obj_attr_v1_process_attribute (OBJ_ATTR_GNU); -#else obj_attr_process_attribute (OBJ_ATTR_GNU); -#endif } #endif /* TC_OBJ_ATTR */ diff --git a/gas/config/obj-elf-attr.h b/gas/config/obj-elf-attr.h index b91edd4276c..3c968fe683a 100644 --- a/gas/config/obj-elf-attr.h +++ b/gas/config/obj-elf-attr.h @@ -44,9 +44,6 @@ extern bool oav1_attr_seen (obj_attr_vendor_t, obj_attr_tag_t); /* Object attributes parsers. */ -#if (TC_OBJ_ATTR_v1) -extern obj_attr_tag_t obj_attr_v1_process_attribute (obj_attr_vendor_t); -#endif /* (TC_OBJ_ATTR_v1) */ extern obj_attr_tag_t obj_attr_process_attribute (obj_attr_vendor_t); #if (TC_OBJ_ATTR_v2) extern void obj_attr_process_subsection (void); diff --git a/gas/config/tc-arc.c b/gas/config/tc-arc.c index 7549189cad8..d1a5f7e40c6 100644 --- a/gas/config/tc-arc.c +++ b/gas/config/tc-arc.c @@ -4917,7 +4917,7 @@ arc_extcorereg (int opertype) static void arc_attribute (int ignored ATTRIBUTE_UNUSED) { - obj_attr_tag_t tag = obj_attr_v1_process_attribute (OBJ_ATTR_PROC); + obj_attr_tag_t tag = obj_attr_process_attribute (OBJ_ATTR_PROC); if (tag < NUM_KNOWN_OBJ_ATTRIBUTES) attributes_set_explicitly[tag] = true; diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 04bccaff430..9a4bf4b544b 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -4972,7 +4972,7 @@ s_arm_unwind_raw (int ignored ATTRIBUTE_UNUSED) static void s_arm_eabi_attribute (int ignored ATTRIBUTE_UNUSED) { - obj_attr_tag_t tag = obj_attr_v1_process_attribute (OBJ_ATTR_PROC); + obj_attr_tag_t tag = obj_attr_process_attribute (OBJ_ATTR_PROC); if (tag < NUM_KNOWN_OBJ_ATTRIBUTES) attributes_set_explicitly[tag] = 1; diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c index b679539dd27..1823bd0e15f 100644 --- a/gas/config/tc-m68k.c +++ b/gas/config/tc-m68k.c @@ -7917,7 +7917,7 @@ m68k_elf_cons (int nbytes /* 4=.long */) static void m68k_elf_gnu_attribute (int ignored ATTRIBUTE_UNUSED) { - obj_attr_tag_t tag = obj_attr_v1_process_attribute (OBJ_ATTR_GNU); + obj_attr_tag_t tag = obj_attr_process_attribute (OBJ_ATTR_GNU); /* Check validity of defined m68k tags. */ if (tag == Tag_GNU_M68K_ABI_FP) diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index 7c34948c463..7ba6c1ffee8 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -2540,7 +2540,7 @@ ppc_elf_abiversion (int ignore ATTRIBUTE_UNUSED) static void ppc_elf_gnu_attribute (int ignored ATTRIBUTE_UNUSED) { - obj_attr_tag_t tag = obj_attr_v1_process_attribute (OBJ_ATTR_GNU); + obj_attr_tag_t tag = obj_attr_process_attribute (OBJ_ATTR_GNU); /* Check validity of defined powerpc tags. */ if (tag == Tag_GNU_Power_ABI_FP diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index f1a48bfc0e4..6bcf53832a0 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -5835,7 +5835,7 @@ riscv_convert_symbolic_attribute (const char *name) static void s_riscv_attribute (int ignored ATTRIBUTE_UNUSED) { - obj_attr_tag_t tag = obj_attr_v1_process_attribute (OBJ_ATTR_PROC); + obj_attr_tag_t tag = obj_attr_process_attribute (OBJ_ATTR_PROC); unsigned old_xlen; obj_attribute *attr; diff --git a/gas/config/tc-tic6x.c b/gas/config/tc-tic6x.c index c4d94435886..bfd45f056b4 100644 --- a/gas/config/tc-tic6x.c +++ b/gas/config/tc-tic6x.c @@ -688,7 +688,7 @@ static bool tic6x_attributes_set_explicitly[NUM_KNOWN_OBJ_ATTRIBUTES]; static void s_tic6x_c6xabi_attribute (int ignored ATTRIBUTE_UNUSED) { - obj_attr_tag_t tag = obj_attr_v1_process_attribute (OBJ_ATTR_PROC); + obj_attr_tag_t tag = obj_attr_process_attribute (OBJ_ATTR_PROC); if (tag < NUM_KNOWN_OBJ_ATTRIBUTES) tic6x_attributes_set_explicitly[tag] = true; diff --git a/gas/testsuite/gas/arm/attr-syntax.d b/gas/testsuite/gas/arm/attr-syntax.d index b21e5eb61e5..752b00a6003 100644 --- a/gas/testsuite/gas/arm/attr-syntax.d +++ b/gas/testsuite/gas/arm/attr-syntax.d @@ -1,4 +1,8 @@ #source: attr-syntax.s #notarget: *-*-pe #as: -#error: :1: Error: Attribute name not recognised: made_up_tag.*:3: Error: expected , .*:5: Error: expected , +#error: \A[^\n]+: Assembler messages: +#error: \n[^\n]+: Error: unknown identifier 'made_up_tag' in this context +#error: \n[^\n]+: Error: could not parse attribute tag +#error: \n[^\n]+: Error: syntax error, comma not expected here +#error: \n[^\n]+: Error: syntax error, comma missing here\Z