new file mode 100644
@@ -0,0 +1,47 @@
+# Expect script for AARCH64 ELF tests related to GNU properties.
+# Copyright (C) 2025 Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# 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.
+
+# Exclude non-aarch64-ELF targets.
+if { ![is_elf_format] || ![istarget "aarch64*-*-*"] } {
+ return
+}
+
+load_file $srcdir/$subdir/../lib/aarch64-elf-lib.exp
+
+set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
+
+# See definition of run_ld_link_tests in testsuite/lib/ld-lib.exp for more
+# details.
+# set aarch64elflinktests {
+# {"Build bti-plt-so for PLT tests"
+# "-shared" ""
+# "-I$srcdir/$subdir -defsym __property_bti__=1"
+# {bti-plt-so.s} {} "libbti-plt-so.so"}
+# }
+
+# if [check_shared_lib_support] {
+# run_ld_link_tests $aarch64elflinktests
+# }
+
+foreach t $test_list {
+ # We need to strip the ".d", but can leave the dirname.
+ run_dump_test [file rootname $t] \
+ [list [list as "-I\$srcdir/\$subdir"]]
+}
\ No newline at end of file
new file mode 100644
@@ -0,0 +1,15 @@
+.aeabi_subsection gnu-testing-ba-1-MERGE-AND, optional, uleb128
+.aeabi_attribute 0, 1
+.aeabi_attribute 1, 0
+
+.aeabi_subsection gnu-testing-ba-2-MERGE-AND, optional, uleb128
+.aeabi_attribute 0, 0
+.aeabi_attribute 1, 1
+
+.aeabi_subsection gnu-testing-ba-3-MERGE-ADD, optional, ntbs
+.aeabi_attribute 0, "hello"
+.aeabi_attribute 1, "world"
+
+.aeabi_subsection gnu-testing-ba-5-MERGE-ADD, optional, ntbs
+.aeabi_attribute 0, "hello"
+.aeabi_attribute 1, "world"
new file mode 100644
@@ -0,0 +1,15 @@
+.aeabi_subsection gnu-testing-ba-1-MERGE-AND, optional, uleb128
+.aeabi_attribute 0, 1
+.aeabi_attribute 1, 1
+
+.aeabi_subsection gnu-testing-ba-2-MERGE-AND, optional, uleb128
+.aeabi_attribute 0, 1
+.aeabi_attribute 1, 1
+
+.aeabi_subsection gnu-testing-ba-4-MERGE-ADD, optional, ntbs
+.aeabi_attribute 0, "foo"
+.aeabi_attribute 1, "bar"
+
+.aeabi_subsection gnu-testing-ba-5-MERGE-ADD, optional, ntbs
+.aeabi_attribute 0, "foo"
+.aeabi_attribute 1, "bar"
new file mode 100644
@@ -0,0 +1,7 @@
+# name: Build attributes: mismatch subsection properties with ba-1-all-optional-1
+# source: ba-1-all-optional-1.s
+# source: ba-1-mismatch-subsec-props-with-all-optional-1.s
+# as:
+# ld: -shared
+#error: \A[^\n]*ba-1-all-optional-1\.o, [^:]*ba-1-mismatch-subsec-props-with-all-optional-1\.o: error: parameters of subsection 'gnu-testing-ba-1-MERGE-AND' are mismatching. \(optional, uleb128\) VS \(required, uleb128\)\n
+#error: [^\n]*ba-1-all-optional-1\.o, [^:]*ba-1-mismatch-subsec-props-with-all-optional-1\.o: error: parameters of subsection 'gnu-testing-ba-2-MERGE-AND' are mismatching. \(optional, uleb128\) VS \(optional, ntbs\)
new file mode 100644
@@ -0,0 +1,2 @@
+.aeabi_subsection gnu-testing-ba-1-MERGE-AND, required, uleb128
+.aeabi_subsection gnu-testing-ba-2-MERGE-AND, optional, ntbs
new file mode 100644
@@ -0,0 +1,42 @@
+# name: Build attributes: only one input object is copied to the output object
+# source: ba-1-all-optional-1.s
+# as:
+# ld: -shared
+# readelf: --arch-specific
+
+Subsections:
+ - Name: gnu-testing-ba-1-MERGE-AND
+ Scope: private
+ Length: 37
+ Optional: True
+ Encoding: ULEB128
+ Values:
+ Tag_unknown_0: 1 \(0x1\)
+ Tag_unknown_1: 0 \(0x0\)
+
+ - Name: gnu-testing-ba-2-MERGE-AND
+ Scope: private
+ Length: 37
+ Optional: True
+ Encoding: ULEB128
+ Values:
+ Tag_unknown_0: 0 \(0x0\)
+ Tag_unknown_1: 1 \(0x1\)
+
+ - Name: gnu-testing-ba-3-MERGE-ADD
+ Scope: private
+ Length: 47
+ Optional: True
+ Encoding: asciz
+ Values:
+ Tag_unknown_0: "hello"
+ Tag_unknown_1: "world"
+
+ - Name: gnu-testing-ba-5-MERGE-ADD
+ Scope: private
+ Length: 47
+ Optional: True
+ Encoding: asciz
+ Values:
+ Tag_unknown_0: "hello"
+ Tag_unknown_1: "world"
new file mode 100644
@@ -0,0 +1,53 @@
+# name: Build attributes: 2 files, all optional, 1 more, 1 missing
+# source: ba-1-all-optional-1.s
+# source: ba-1-all-optional-2.s
+# as:
+# ld: -shared
+# readelf: --arch-specific
+
+Subsections:
+ - Name: gnu-testing-ba-1-MERGE-AND
+ Scope: private
+ Length: 37
+ Optional: True
+ Encoding: ULEB128
+ Values:
+ Tag_unknown_0: 1 \(0x1\)
+ Tag_unknown_1: 0 \(0x0\)
+
+ - Name: gnu-testing-ba-2-MERGE-AND
+ Scope: private
+ Length: 37
+ Optional: True
+ Encoding: ULEB128
+ Values:
+ Tag_unknown_0: 0 \(0x0\)
+ Tag_unknown_1: 1 \(0x1\)
+
+ - Name: gnu-testing-ba-3-MERGE-ADD
+ Scope: private
+ Length: 47
+ Optional: True
+ Encoding: asciz
+ Values:
+ Tag_unknown_0: "hello"
+ Tag_unknown_1: "world"
+
+ - Name: gnu-testing-ba-4-MERGE-ADD
+ Scope: private
+ Length: 43
+ Optional: True
+ Encoding: asciz
+ Values:
+ Tag_unknown_0: "foo"
+ Tag_unknown_1: "bar"
+
+ - Name: gnu-testing-ba-5-MERGE-ADD
+ Scope: private
+ Length: 55
+ Optional: True
+ Encoding: asciz
+ Values:
+ Tag_unknown_0: "hello\+foo"
+ Tag_unknown_1: "world\+bar"
+
new file mode 100644
@@ -0,0 +1,11 @@
+.aeabi_subsection gnu-testing-ba-1-MERGE-AND, optional, uleb128
+.aeabi_attribute 0, 1
+.aeabi_attribute 1, 1
+.aeabi_attribute 2, 1 // Unknown tag
+.aeabi_attribute 3, 1 // Unknown tag
+
+.aeabi_subsection gnu-testing-ba-2-MERGE-ADD, optional, ntbs
+.aeabi_attribute 0, "foo"
+.aeabi_attribute 1, "bar"
+.aeabi_attribute 2, "foo2" // Unknown tag
+.aeabi_attribute 3, "foo3" // Unknown tag
new file mode 100644
@@ -0,0 +1,11 @@
+.aeabi_subsection gnu-testing-ba-1-MERGE-AND, optional, uleb128
+.aeabi_attribute 0, 1
+.aeabi_attribute 1, 1
+.aeabi_attribute 2, 1 // Unknown tag
+.aeabi_attribute 4, 1 // Unknown tag
+
+.aeabi_subsection gnu-testing-ba-2-MERGE-ADD, optional, ntbs
+.aeabi_attribute 0, "foo"
+.aeabi_attribute 1, "bar"
+.aeabi_attribute 2, "foo2" // Unknown tag
+.aeabi_attribute 4, "foo4" // Unknown tag
new file mode 100644
@@ -0,0 +1,25 @@
+# name: Build attributes: unknown attribute inside known subsection should be removed from the output.
+# source: ba-2-mix-unknown-and-known-attr-known-subsection-1.s
+# source: ba-2-mix-unknown-and-known-attr-known-subsection-2.s
+# as:
+# ld: -shared
+# readelf: --arch-specific
+
+Subsections:
+ - Name: gnu-testing-ba-1-MERGE-AND
+ Scope: private
+ Length: 37
+ Optional: True
+ Encoding: ULEB128
+ Values:
+ Tag_unknown_0: 1 \(0x1\)
+ Tag_unknown_1: 1 \(0x1\)
+
+ - Name: gnu-testing-ba-2-MERGE-ADD
+ Scope: private
+ Length: 51
+ Optional: True
+ Encoding: asciz
+ Values:
+ Tag_unknown_0: "foo\+foo"
+ Tag_unknown_1: "bar\+bar"
new file mode 100644
@@ -0,0 +1,19 @@
+.aeabi_subsection gnu-testing-ba-1-MERGE-AND, optional, uleb128
+.aeabi_attribute 0, 1
+.aeabi_attribute 1, 0
+
+.aeabi_subsection private-1, optional, uleb128
+.aeabi_attribute 0, 0
+.aeabi_attribute 1, 1
+
+.aeabi_subsection private-2, optional, ntbs
+.aeabi_attribute 0, "hello"
+.aeabi_attribute 1, "world"
+
+.aeabi_subsection private-4, optional, uleb128
+.aeabi_attribute 0, 1
+.aeabi_attribute 1, 1
+
+.aeabi_subsection gnu-testing-ba-2-MERGE-ADD, optional, ntbs
+.aeabi_attribute 0, "hello"
+.aeabi_attribute 1, "world"
new file mode 100644
@@ -0,0 +1,19 @@
+.aeabi_subsection gnu-testing-ba-1-MERGE-AND, optional, uleb128
+.aeabi_attribute 0, 1
+.aeabi_attribute 1, 1
+
+.aeabi_subsection private-1, optional, uleb128
+.aeabi_attribute 0, 1
+.aeabi_attribute 1, 1
+
+.aeabi_subsection private-2, optional, ntbs
+.aeabi_attribute 0, "foo"
+.aeabi_attribute 1, "bar"
+
+.aeabi_subsection private-3, optional, uleb128
+.aeabi_attribute 0, 1
+.aeabi_attribute 1, 1
+
+.aeabi_subsection gnu-testing-ba-2-MERGE-ADD, optional, ntbs
+.aeabi_attribute 0, "foo"
+.aeabi_attribute 1, "bar"
new file mode 100644
@@ -0,0 +1,26 @@
+# name: Build attributes: unknown subsections are removed from the output.
+# source: ba-2-mix-unknown-and-known-subsections-1.s
+# source: ba-2-mix-unknown-and-known-subsections-2.s
+# as:
+# ld: -shared
+# readelf: --arch-specific
+
+Subsections:
+ - Name: gnu-testing-ba-1-MERGE-AND
+ Scope: private
+ Length: 37
+ Optional: True
+ Encoding: ULEB128
+ Values:
+ Tag_unknown_0: 1 \(0x1\)
+ Tag_unknown_1: 0 \(0x0\)
+
+ - Name: gnu-testing-ba-2-MERGE-ADD
+ Scope: private
+ Length: 55
+ Optional: True
+ Encoding: asciz
+ Values:
+ Tag_unknown_0: "hello\+foo"
+ Tag_unknown_1: "world\+bar"
+
new file mode 100644
@@ -0,0 +1,3 @@
+.aeabi_subsection gnu-testing-ba-1-MERGE-AND, required, uleb128
+.aeabi_attribute 0, 1
+.aeabi_attribute 1, 0
new file mode 100644
@@ -0,0 +1,3 @@
+.aeabi_subsection gnu-testing-ba-1-MERGE-AND, required, uleb128
+.aeabi_attribute 0, 1
+.aeabi_attribute 1, 0
new file mode 100644
@@ -0,0 +1,3 @@
+.aeabi_subsection gnu-testing-ba-1-MERGE-AND, required, uleb128
+.aeabi_attribute 0, 1
+.aeabi_attribute 1, 1
new file mode 100644
@@ -0,0 +1,7 @@
+# name: Build attributes: combine non-matching required subsections
+# source: ba-2-required-subsec-A-1.s
+# source: ba-2-required-subsec-B.s
+# source: ba-2-required-subsec-A-2.s
+# as:
+# ld: -shared
+#error: \A[^\n]*ba-2-required-subsec-A-1\.o, [^:]*ba-2-required-subsec-B\.o: error: mismatching values 0x0 and 0x1 for required object attribute 'GNUTestTag_1' in subsection 'gnu-testing-ba-1-MERGE-AND'
new file mode 100644
@@ -0,0 +1,16 @@
+# name: Build attributes: combine matching required subsections
+# source: ba-2-required-subsec-A-1.s
+# source: ba-2-required-subsec-A-2.s
+# as:
+# ld: -shared
+# readelf: --arch-specific
+
+Subsections:
+ - Name: gnu-testing-ba-1-MERGE-AND
+ Scope: private
+ Length: 37
+ Optional: False
+ Encoding: ULEB128
+ Values:
+ Tag_unknown_0: 1 \(0x1\)
+ Tag_unknown_1: 0 \(0x0\)