From: Matthieu Longo Date: Thu, 10 Apr 2025 14:16:31 +0000 (+0100) Subject: gnu directives: gas/readelf tests for gnu attributes v2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=536b361895d4a4870c3025763655669c89e8b0d7;p=thirdparty%2Fbinutils-gdb.git gnu directives: gas/readelf tests for gnu attributes v2 These tests are a copy-paste of the generic parsing tests for AArch64. The added tests cover the parsing of the new assembly directives (gnu_subsection and gnu_attribute), the serialization of the Object Attributes v2 (OAv2) data into an object file, and the dumping of those data via readelf. The parsing tests focus on the following points: - the syntax of the new directives. - the recognition of generic tokens like: NTBS, ULEB128, required, optional. The dumping tests focus on: - the OAv2 population into the correct section assigned by the backend. - the merge of the subsections and attributes when they are declared several times inside respectively the same compilation unit, and subsection. - the sorting of OAv2 before the serialization. --- diff --git a/binutils/testsuite/lib/binutils-common.exp b/binutils/testsuite/lib/binutils-common.exp index e5cb24e594f..37aa2a25af2 100644 --- a/binutils/testsuite/lib/binutils-common.exp +++ b/binutils/testsuite/lib/binutils-common.exp @@ -507,6 +507,39 @@ proc gas_sframe_check {} { return $check_as_sframe_result } +# Whether a target supports Object Attributes v1 +proc supports_oa_v1 {} { + if { ! [is_elf_format] } { + return 0 + } + if { [istarget arc-*-*] + || [istarget arm*-*-*] + || [istarget csky*-*-*] + || [istarget loongarch*-*-*] + || [istarget m68*-*-*] + || [istarget mips*-*-*] + || [istarget msp*-*-*] + || [istarget powerpc*-*-*] + || [istarget riscv*-*-*] + || [istarget s390*-*-*] + || [istarget sparc*-*-*] + || [istarget tic6x*-*-*] } { + return 1 + } + return 0 +} + +# Whether a target supports Object Attributes v2 +proc supports_oa_v2 {} { + if { ! [is_elf_format] } { + return 0 + } + if { [istarget aarch64*-*-*] } { + return 1 + } + return 0 +} + # get_relative_path FROM TO # # Return a relative path to TO starting from FROM, which is usually diff --git a/gas/testsuite/gas/gnu-attributes/gnu-attributes.exp b/gas/testsuite/gas/gnu-attributes/gnu-attributes.exp new file mode 100644 index 00000000000..82a35a7b1ae --- /dev/null +++ b/gas/testsuite/gas/gnu-attributes/gnu-attributes.exp @@ -0,0 +1,20 @@ +# Copyright (C) 2025 Free Software Foundation, Inc. + +# This program 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 of the License, or +# (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + +# +# Generic tests for GNU attributes v1 and v2 +# +run_dump_tests [lsort [glob -nocomplain $srcdir/$subdir/*.d]] diff --git a/gas/testsuite/gas/gnu-attributes/oa-no-gnu-attribute-directive.d b/gas/testsuite/gas/gnu-attributes/oa-no-gnu-attribute-directive.d new file mode 100644 index 00000000000..41952765467 --- /dev/null +++ b/gas/testsuite/gas/gnu-attributes/oa-no-gnu-attribute-directive.d @@ -0,0 +1,4 @@ +# name: GNU attributes v1/v2: no support for directive .gnu_attribute +# notarget: [supports_oa_v1] [supports_oa_v2] +# error: \A[^\n]+: Assembler messages: +# error: \n[^\n]+: Error: unknown pseudo-op: `\.gnu_attribute'\Z diff --git a/gas/testsuite/gas/gnu-attributes/oa-no-gnu-attribute-directive.s b/gas/testsuite/gas/gnu-attributes/oa-no-gnu-attribute-directive.s new file mode 100644 index 00000000000..a3cdcae37c9 --- /dev/null +++ b/gas/testsuite/gas/gnu-attributes/oa-no-gnu-attribute-directive.s @@ -0,0 +1 @@ + .gnu_attribute 0, 1 diff --git a/gas/testsuite/gas/gnu-attributes/oa-no-gnu-subsection-directive.d b/gas/testsuite/gas/gnu-attributes/oa-no-gnu-subsection-directive.d new file mode 100644 index 00000000000..bc262c26d22 --- /dev/null +++ b/gas/testsuite/gas/gnu-attributes/oa-no-gnu-subsection-directive.d @@ -0,0 +1,4 @@ +# name: GNU attributes v2: no support for directive .gnu_subsection +# notarget: [supports_oa_v2] +# error: \A[^\n]+: Assembler messages: +# error: \n[^\n]+: Error: unknown pseudo-op: `\.gnu_subsection'\Z diff --git a/gas/testsuite/gas/gnu-attributes/oa-no-gnu-subsection-directive.s b/gas/testsuite/gas/gnu-attributes/oa-no-gnu-subsection-directive.s new file mode 100644 index 00000000000..8b5cc3908bf --- /dev/null +++ b/gas/testsuite/gas/gnu-attributes/oa-no-gnu-subsection-directive.s @@ -0,0 +1 @@ + .gnu_subsection gnu_foo_1, optional, ULEB128 diff --git a/gas/testsuite/gas/gnu-attributes/oav2-failures-1.d b/gas/testsuite/gas/gnu-attributes/oav2-failures-1.d new file mode 100644 index 00000000000..2a244d46a98 --- /dev/null +++ b/gas/testsuite/gas/gnu-attributes/oav2-failures-1.d @@ -0,0 +1,3 @@ +# name: GNU attributes v2: error cases +# target: [supports_oa_v2] +# error_output: oav2-failures-1.l diff --git a/gas/testsuite/gas/gnu-attributes/oav2-failures-1.l b/gas/testsuite/gas/gnu-attributes/oav2-failures-1.l new file mode 100644 index 00000000000..f2545838c74 --- /dev/null +++ b/gas/testsuite/gas/gnu-attributes/oav2-failures-1.l @@ -0,0 +1,40 @@ +.*: Assembler messages: +.*: Error: declaration of an attribute outside the scope of an attribute subsection +.*: Error: attribute '1' cannot be redefined +.*: Error: unexpected value '-1', expected `unsigned integer' instead +.*: Error: could not parse attribute tag +.*: Error: unknown identifier 'Tag_Unknown' in this context +.*: Error: could not parse attribute tag +.*: Error: unexpected value '-1', expected `unsigned integer' instead +.*: Error: could not parse attribute value +.*: Error: unexpected `string' "foo", expected `unsigned integer' instead +.*: Error: could not parse attribute value +.*: Error: unexpected integer '1', expected `string' instead +.*: Error: could not parse attribute value +.*: Error: attribute '4' cannot be redefined +.*: Error: comprehension and encoding of a subsection cannot be omitted on the first declaration +.*: Error: incompatible redeclaration of subsection vendor_1_subsection_3 +.*: Info: .* +.*: Error: incompatible redeclaration of subsection vendor_1_subsection_3 +.*: Info: .* +.*: Error: incompatible redeclaration of subsection vendor_1_subsection_3 +.*: Info: .* +.*: Error: unknown identifier 'ntbs' in this context +.*: Error: unknown identifier 'uleb128' in this context +.*: Error: expression '.vendor' does not resolve to an integer +.*: Error: fell back to integer literal extraction from expression, but expected `identifier' instead +.*: Error: expected , , +.*: Error: unknown identifier 'uleb128' in this context +.*: Error: unknown identifier 'optial' in this context +.*: Error: unknown identifier 'ul128' in this context +.*: Error: invalid value '2', expected values for are .* +.*: Error: invalid value '2', expected values for are .* +.*: Error: syntax error, comma not expected here +.*: Error: junk at end of line, first unrecognized character is `,' +.*: Error: syntax error, comma not expected here +.*: Error: syntax error, comma missing here +.*: Error: syntax error, comma not expected here +.*: Error: junk at end of line, first unrecognized character is `,' +.*: Error: syntax error, comma not expected here +.*: Error: junk at end of line, first unrecognized character is `1' +.*: Error: attribute '1' cannot be redefined diff --git a/gas/testsuite/gas/gnu-attributes/oav2-failures-1.s b/gas/testsuite/gas/gnu-attributes/oav2-failures-1.s new file mode 100644 index 00000000000..9718d1c0e1a --- /dev/null +++ b/gas/testsuite/gas/gnu-attributes/oav2-failures-1.s @@ -0,0 +1,70 @@ + .set ATTR_TYPE_uleb128, 0 + .set ATTR_TYPE_asciz, 1 + + /* The definition of an attribute cannot appear before a subsection was + declared. */ + .gnu_attribute 1, 0 + + /* gnu_attribute with the same key should have the same value in the + same compilation unit. */ + .gnu_subsection vendor_1_subsection_1, optional, uleb128 + .gnu_attribute 1, 0 + .gnu_attribute 1, 1 + + /* Only unsigned integer are allowed for attribute keys. */ + .gnu_attribute -1, 1 + /* Unknown tag identifier. */ + .aeabi_attribute Tag_Unknown, 1 + + /* Mismatch between the type expected from the subsection definition, + and the type provided to the attribute directive. */ + .gnu_attribute 2, -1 + .gnu_attribute 3, "foo" + .gnu_subsection vendor_1_subsection_2, optional, ntbs + /* Mismatch between type of the value and the one expected by the + subsection. */ + .gnu_attribute 1, 1 + /* gnu_attribute with the same key should have the same value in the + same compilation unit. */ + .gnu_attribute 4, "ABC" + .gnu_attribute 4, "DEF" + + /* The comprehension and encoding cannot be omitted on the first + declaration. */ + .gnu_subsection vendor_1_subsection_3 + + /* Subsections with the same name should have the same parameters. */ + .gnu_subsection vendor_1_subsection_3, required, ntbs + .gnu_subsection vendor_1_subsection_3, optional, ntbs + .gnu_subsection vendor_1_subsection_3, required, uleb128 + .gnu_subsection vendor_1_subsection_3, optional, uleb128 + + /* Omitted paramaters have to be omitted in the reverse order. */ + .gnu_subsection vendor_1_subsection_3, ntbs + .gnu_subsection vendor_1_subsection_3, uleb128 + + /* Invalid subsection name should raise an error. */ + .gnu_subsection .vendor, optional, uleb128 + + /* Swap and . */ + .gnu_subsection vendor_1_subsection_4, uleb128, optional + + /* Unknown identifier for , and . */ + .gnu_subsection vendor_1_subsection_4, optial, uleb128 + .gnu_subsection vendor_1_subsection_4, optional, ul128 + + /* Invalid value for optional and format. */ + .gnu_subsection vendor_1_subsection_4, 2, 1 + .gnu_subsection vendor_1_subsection_4, 1, 2 + + /* Wrong comma in the declaration of a subsection. */ + .gnu_subsection vendor_1_subsection_4, , 1 + .gnu_subsection vendor_1_subsection_4, 1, 1, 1 + .gnu_subsection , vendor_1_subsection_4, 1 + .gnu_subsection vendor_1_subsection_4, 1 1 + + /* Wrong comma in the declaration of an attribute. */ + .aeabi_attribute 1, , 1 + .aeabi_attribute 1, "dead", 1, 1 + .aeabi_attribute , 1, 1 + .aeabi_attribute 1, "beef" 1 diff --git a/gas/testsuite/gas/gnu-attributes/oav2-interleaved-subsections.d b/gas/testsuite/gas/gnu-attributes/oav2-interleaved-subsections.d new file mode 100644 index 00000000000..3b3ed689edc --- /dev/null +++ b/gas/testsuite/gas/gnu-attributes/oav2-interleaved-subsections.d @@ -0,0 +1,34 @@ +# name: GNU attributes v2: correct context switching between interleaved subsections +# target: [supports_oa_v2] +# readelf: -A + +Subsections: + - Name:[ ]+foo_1 + Scope:[ ]+private + Length:[ ]+20 + Comprehension:[ ]+optional + Encoding:[ ]+ULEB128 + Values: + +Tag_unknown_1:[ ]+1 .* + +Tag_unknown_2:[ ]+0 .* + +Tag_unknown_3:[ ]+0 .* + +Tag_unknown_4:[ ]+0 .* + + - Name:[ ]+gnu_abi + Scope:[ ]+public + Length:[ ]+18 + Comprehension:[ ]+required + Encoding:[ ]+ULEB128 + Values: + +Tag_unknown_1:[ ]+1 .* + +Tag_unknown_2:[ ]+1 .* + + - Name:[ ]+gnu_feature_and_bits + Scope:[ ]+public + Length:[ ]+33 + Comprehension:[ ]+optional + Encoding:[ ]+ULEB128 + Values: + +Tag_unknown_0:[ ]+1 .* + +Tag_unknown_1:[ ]+0 .* + +Tag_unknown_2:[ ]+1 .* diff --git a/gas/testsuite/gas/gnu-attributes/oav2-interleaved-subsections.s b/gas/testsuite/gas/gnu-attributes/oav2-interleaved-subsections.s new file mode 100644 index 00000000000..196f6e230ed --- /dev/null +++ b/gas/testsuite/gas/gnu-attributes/oav2-interleaved-subsections.s @@ -0,0 +1,32 @@ + .gnu_subsection gnu_abi, required, uleb128 + + .gnu_subsection gnu_feature_and_bits, optional, uleb128 + .gnu_attribute 0, 1 + + .gnu_subsection gnu_feature_and_bits + + .gnu_subsection foo_1, optional, uleb128 + .gnu_attribute 1, 1 + + .gnu_subsection gnu_abi + .gnu_attribute 2, 1 + + .gnu_subsection gnu_feature_and_bits + .gnu_attribute 2, 1 + + .gnu_subsection foo_1 + .gnu_attribute 2, 0 + + .gnu_subsection gnu_abi + .gnu_attribute 1, 1 + + .gnu_subsection gnu_abi + .gnu_subsection gnu_feature_and_bits + .gnu_attribute 1, 0 + + .gnu_subsection foo_1 + .gnu_attribute 3, 0 + .gnu_attribute 4, 0 + + .gnu_subsection gnu_feature_and_bits + .gnu_attribute 1, 0 diff --git a/gas/testsuite/gas/gnu-attributes/oav2-subsection-parsing.d b/gas/testsuite/gas/gnu-attributes/oav2-subsection-parsing.d new file mode 100644 index 00000000000..25b1b6d6007 --- /dev/null +++ b/gas/testsuite/gas/gnu-attributes/oav2-subsection-parsing.d @@ -0,0 +1,74 @@ +# name: GNU attributes v2: parsing of subsections +# target: [supports_oa_v2] +# readelf: -A + +Subsections: + - Name:[ ]+foo_01 + Scope:[ ]+private + Length:[ ]+13 + Comprehension:[ ]+required + Encoding:[ ]+ULEB128 + Values: + + - Name:[ ]+foo_02 + Scope:[ ]+private + Length:[ ]+13 + Comprehension:[ ]+required + Encoding:[ ]+NTBS + Values: + + - Name:[ ]+foo_03 + Scope:[ ]+private + Length:[ ]+13 + Comprehension:[ ]+optional + Encoding:[ ]+ULEB128 + Values: + + - Name:[ ]+foo_04 + Scope:[ ]+private + Length:[ ]+13 + Comprehension:[ ]+optional + Encoding:[ ]+NTBS + Values: + + - Name:[ ]+foo_05 + Scope:[ ]+private + Length:[ ]+13 + Comprehension:[ ]+required + Encoding:[ ]+ULEB128 + Values: + + - Name:[ ]+foo_06 + Scope:[ ]+private + Length:[ ]+13 + Comprehension:[ ]+optional + Encoding:[ ]+ULEB128 + Values: + + - Name:[ ]+foo_07 + Scope:[ ]+private + Length:[ ]+13 + Comprehension:[ ]+optional + Encoding:[ ]+NTBS + Values: + + - Name:[ ]+foo_08 + Scope:[ ]+private + Length:[ ]+13 + Comprehension:[ ]+required + Encoding:[ ]+NTBS + Values: + + - Name:[ ]+foo_09 + Scope:[ ]+private + Length:[ ]+13 + Comprehension:[ ]+required + Encoding:[ ]+ULEB128 + Values: + + - Name:[ ]+foo_10 + Scope:[ ]+private + Length:[ ]+13 + Comprehension:[ ]+optional + Encoding:[ ]+NTBS + Values: diff --git a/gas/testsuite/gas/gnu-attributes/oav2-subsection-parsing.s b/gas/testsuite/gas/gnu-attributes/oav2-subsection-parsing.s new file mode 100644 index 00000000000..79ad53dcefe --- /dev/null +++ b/gas/testsuite/gas/gnu-attributes/oav2-subsection-parsing.s @@ -0,0 +1,37 @@ + .set ATTR_TYPE_uleb128, 0 + .set ATTR_TYPE_asciz, 1 + + .set SUBSEC_required, 0 + .set SUBSEC_optional, 1 + + /* Integer literals. */ + .gnu_subsection foo_01, 0, 0 + .gnu_subsection foo_02, 0, 1 + .gnu_subsection foo_03, 1, 0 + .gnu_subsection foo_04, 1, 1 + + /* Known identifiers. */ + .gnu_subsection foo_05, required, uleb128 + .gnu_subsection foo_06, optional, ULEB128 + .gnu_subsection foo_07, optional, ntbs + .gnu_subsection foo_08, required, NTBS + + /* Symbol look-up. */ + .gnu_subsection foo_09, SUBSEC_required, ATTR_TYPE_uleb128 + .gnu_subsection foo_10, SUBSEC_optional, ATTR_TYPE_asciz + + /* Switch back to the section without specifying the comprehension and + encoding. */ + .gnu_subsection foo_01 + .gnu_subsection foo_03 + + /* Switch back to the section without specifying the encoding. */ + .gnu_subsection foo_01, required + .gnu_subsection foo_03, optional + + /* Switch back to the section while specifying the comprehension and + encoding. */ + .gnu_subsection foo_01, 0, 0 + .gnu_subsection foo_02, 0, 1 + .gnu_subsection foo_01, required, uleb128 + .gnu_subsection foo_02, required, ntbs diff --git a/gas/testsuite/gas/gnu-attributes/oav2-success-1.d b/gas/testsuite/gas/gnu-attributes/oav2-success-1.d new file mode 100644 index 00000000000..4bc7fd847a3 --- /dev/null +++ b/gas/testsuite/gas/gnu-attributes/oav2-success-1.d @@ -0,0 +1,52 @@ +# name: GNU attributes v2: dump subsections content from attributes vendor section. +# target: [supports_oa_v2] +# readelf: -A + +Subsections: + - Name:[ ]+foo_1 + Scope:[ ]+private + Length:[ ]+22 + Comprehension:[ ]+optional + Encoding:[ ]+ULEB128 + Values: + +Tag_unknown_0:[ ]+1 .* + +Tag_unknown_1:[ ]+1 .* + +Tag_unknown_2:[ ]+1 .* + +Tag_unknown_3:[ ]+1 .* + +Tag_unknown_10:[ ]+2 .* + + - Name:[ ]+gnu_foo_1 + Scope:[ ]+public + Length:[ ]+20 + Comprehension:[ ]+optional + Encoding:[ ]+ULEB128 + Values: + +Tag_unknown_2:[ ]+65 .* + +Tag_unknown_3:[ ]+1 .* + + - Name:[ ]+gnu_foo_2 + Scope:[ ]+public + Length:[ ]+25 + Comprehension:[ ]+required + Encoding:[ ]+NTBS + Values: + +Tag_unknown_2:[ ]+"TEST2" + +Tag_unknown_4:[ ]+"" + + - Name:[ ]+gnu_foo_3 + Scope:[ ]+public + Length:[ ]+22 + Comprehension:[ ]+required + Encoding:[ ]+NTBS + Values: + +Tag_unknown_4:[ ]+"TEST" + + - Name:[ ]+gnu_testing_foo_MERGE_AND + Scope:[ ]+private + Length:[ ]+38 + Comprehension:[ ]+optional + Encoding:[ ]+ULEB128 + Values: + +Tag_unknown_0:[ ]+0 .* + +Tag_unknown_1:[ ]+1 .* + +Tag_unknown_2:[ ]+1 .* diff --git a/gas/testsuite/gas/gnu-attributes/oav2-success-1.s b/gas/testsuite/gas/gnu-attributes/oav2-success-1.s new file mode 100644 index 00000000000..affa9ef33ee --- /dev/null +++ b/gas/testsuite/gas/gnu-attributes/oav2-success-1.s @@ -0,0 +1,32 @@ + .set ATTR_TYPE_uleb128, 0 + .set ATTR_TYPE_asciz, 1 + + .set SUBSEC_required, 0 + .set SUBSEC_optional, 1 + + .gnu_subsection foo_1, 1, ATTR_TYPE_uleb128 + + .set Tag_Feature_foo, 2 + .set Tag_Feature_bar, 3 + + .gnu_attribute Tag_Feature_bar, 1 + .gnu_attribute 0, 1 + .gnu_attribute 1, 1 + .gnu_attribute Tag_Feature_foo, 1 + .gnu_attribute 0xa, (0xff + ~0xfc) // 255 - 253 = 2 + + .gnu_subsection gnu_foo_1, 1, ATTR_TYPE_uleb128 + .gnu_attribute Tag_Feature_bar, 1 + .gnu_attribute Tag_Feature_foo, 'A' + + .gnu_subsection gnu_foo_2, 0, ATTR_TYPE_asciz + .gnu_attribute 4, "" + .gnu_attribute 2, "TEST2" + + .gnu_subsection gnu_foo_3, required, ntbs + .gnu_attribute 4, "TEST" + + .gnu_subsection gnu_testing_foo_MERGE_AND, optional, ULEB128 + .gnu_attribute GNUTestTag_0, 0 + .gnu_attribute GNUTestTag_1, 1 + .gnu_attribute 2, 1