[4/4] aarch64: handle STO_AARCH64_VARIANT_PCS in bfd

Message ID 7944950f-9349-1cb9-af03-c7bafe249168@arm.com
State New
Headers show
Series
  • aarch64: Add STO_AARCH64_VARIANT_PCS support
Related show

Commit Message

Szabolcs Nagy May 23, 2019, 11:11 a.m.
Propagate STO_AARCH64_VARIANT_PCS st_other attribute to the output and
add DT_AARCH64_VARIANT_PCS dynamic tag if necessary.

Mismatching attributes are not diagnosed.

bfd/ChangeLog:

2019-05-22  Szabolcs Nagy  <szabolcs.nagy@arm.com>

	* elfnn-aarch64.c (elfNN_aarch64_merge_symbol_attribute): New function.
	(struct elf_aarch64_link_hash_table): Add variant_pcs member.
	(elfNN_aarch64_allocate_dynrelocs): Update variant_pcs.
	(elfNN_aarch64_size_dynamic_sections): Add DT_AARCH64_VARIANT_PCS.
	(elf_backend_merge_symbol_attribute): Define.

ld/ChangeLog:

2019-05-22  Szabolcs Nagy  <szabolcs.nagy@arm.com>

	* testsuite/ld-aarch64/aarch64-elf.exp: Add new tests.
	* testsuite/ld-aarch64/variant_pcs-1.s: New asm for tests.
	* testsuite/ld-aarch64/variant_pcs-2.s: New asm for tests.
	* testsuite/ld-aarch64/variant_pcs-now.d: New test.
	* testsuite/ld-aarch64/variant_pcs-r.d: New test.
	* testsuite/ld-aarch64/variant_pcs-shared.d: New test.
	* testsuite/ld-aarch64/variant_pcs.ld: New linker script for tests.

Comments

Christophe Lyon May 26, 2019, 8:50 a.m. | #1
On Thu, 23 May 2019 at 13:11, Szabolcs Nagy <Szabolcs.Nagy@arm.com> wrote:
>

> Propagate STO_AARCH64_VARIANT_PCS st_other attribute to the output and

> add DT_AARCH64_VARIANT_PCS dynamic tag if necessary.

>

> Mismatching attributes are not diagnosed.

>

> bfd/ChangeLog:

>

> 2019-05-22  Szabolcs Nagy  <szabolcs.nagy@arm.com>

>

>         * elfnn-aarch64.c (elfNN_aarch64_merge_symbol_attribute): New function.

>         (struct elf_aarch64_link_hash_table): Add variant_pcs member.

>         (elfNN_aarch64_allocate_dynrelocs): Update variant_pcs.

>         (elfNN_aarch64_size_dynamic_sections): Add DT_AARCH64_VARIANT_PCS.

>         (elf_backend_merge_symbol_attribute): Define.

>

> ld/ChangeLog:

>

> 2019-05-22  Szabolcs Nagy  <szabolcs.nagy@arm.com>

>

>         * testsuite/ld-aarch64/aarch64-elf.exp: Add new tests.

>         * testsuite/ld-aarch64/variant_pcs-1.s: New asm for tests.

>         * testsuite/ld-aarch64/variant_pcs-2.s: New asm for tests.

>         * testsuite/ld-aarch64/variant_pcs-now.d: New test.

>         * testsuite/ld-aarch64/variant_pcs-r.d: New test.

>         * testsuite/ld-aarch64/variant_pcs-shared.d: New test.

>         * testsuite/ld-aarch64/variant_pcs.ld: New linker script for tests.


Hi,

I have noticed that some new tests fail on aarch64-elf:
FAIL: ld-aarch64/variant_pcs-now
FAIL: ld-aarch64/variant_pcs-shared

Christophe
Szabolcs Nagy May 28, 2019, 11:07 a.m. | #2
On 26/05/2019 09:50, Christophe Lyon wrote:
> I have noticed that some new tests fail on aarch64-elf:

> FAIL: ld-aarch64/variant_pcs-now

> FAIL: ld-aarch64/variant_pcs-shared


Sorry. committed the attached fix for the tests as obvious.
From 65f381e729bedb933f3e1376e7f53f0ff63ac9a8 Mon Sep 17 00:00:00 2001
From: Szabolcs Nagy <szabolcs.nagy@arm.com>

Date: Tue, 28 May 2019 11:48:08 +0100
Subject: [PATCH] aarch64: fix variant_pcs ld tests

Force sysv hash style for reliable symbol table layout.

ld/ChangeLog:

	* testsuite/ld-aarch64/variant_pcs-now.d: Use --hash-style=sysv.
	* testsuite/ld-aarch64/variant_pcs-shared.d: Likewise.
---
 ld/ChangeLog                                 |  5 ++
 ld/testsuite/ld-aarch64/variant_pcs-now.d    | 77 ++++++++++----------
 ld/testsuite/ld-aarch64/variant_pcs-shared.d | 77 ++++++++++----------
 3 files changed, 81 insertions(+), 78 deletions(-)

diff --git a/ld/ChangeLog b/ld/ChangeLog
index 36d866f465..581be2e4c8 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,8 @@
+2019-05-28  Szabolcs Nagy  <szabolcs.nagy@arm.com>
+
+	* testsuite/ld-aarch64/variant_pcs-now.d: Use --hash-style=sysv.
+	* testsuite/ld-aarch64/variant_pcs-shared.d: Likewise.
+
 2019-05-27  Alan Modra  <amodra@gmail.com>
 
 	PR 24596
diff --git a/ld/testsuite/ld-aarch64/variant_pcs-now.d b/ld/testsuite/ld-aarch64/variant_pcs-now.d
index fc238929da..c3f48fe847 100644
--- a/ld/testsuite/ld-aarch64/variant_pcs-now.d
+++ b/ld/testsuite/ld-aarch64/variant_pcs-now.d
@@ -1,34 +1,34 @@
 #source: variant_pcs-1.s
 #source: variant_pcs-2.s
-#ld: -shared -T variant_pcs.ld -z now
+#ld: -shared --hash-style=sysv -T variant_pcs.ld -z now
 #readelf: -rsW
 
 Relocation section '\.rela\.plt' at offset 0x11000 contains 12 entries:
     Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
 0000000000009020  0000000100000402 R_AARCH64_JUMP_SLOT    0000000000000000 f_base_global_default_undef \+ 0
 0000000000009028  0000000200000402 R_AARCH64_JUMP_SLOT    0000000000000000 f_spec_global_default_undef \+ 0
-0000000000009030  0000000500000402 R_AARCH64_JUMP_SLOT    0000000000008000 f_base_global_default_def \+ 0
-0000000000009038  0000000600000402 R_AARCH64_JUMP_SLOT    0000000000008000 f_spec_global_default_def \+ 0
+0000000000009030  0000000400000402 R_AARCH64_JUMP_SLOT    0000000000008000 f_base_global_default_def \+ 0
+0000000000009038  0000000500000402 R_AARCH64_JUMP_SLOT    0000000000008000 f_spec_global_default_def \+ 0
 0000000000009040  0000000000000408 R_AARCH64_IRELATIVE                       8000
-0000000000009048  0000000400000402 R_AARCH64_JUMP_SLOT    f_spec_global_default_ifunc\(\) f_spec_global_default_ifunc \+ 0
+0000000000009048  0000000300000402 R_AARCH64_JUMP_SLOT    f_spec_global_default_ifunc\(\) f_spec_global_default_ifunc \+ 0
 0000000000009050  0000000000000408 R_AARCH64_IRELATIVE                       8000
-0000000000009058  0000000300000402 R_AARCH64_JUMP_SLOT    f_base_global_default_ifunc\(\) f_base_global_default_ifunc \+ 0
+0000000000009058  0000000600000402 R_AARCH64_JUMP_SLOT    f_base_global_default_ifunc\(\) f_base_global_default_ifunc \+ 0
 0000000000009060  0000000000000408 R_AARCH64_IRELATIVE                       8038
-0000000000009068  0000000000000408 R_AARCH64_IRELATIVE                       8038
+0000000000009068  0000000000000408 R_AARCH64_IRELATIVE                       8000
 0000000000009070  0000000000000408 R_AARCH64_IRELATIVE                       8000
-0000000000009078  0000000000000408 R_AARCH64_IRELATIVE                       8000
+0000000000009078  0000000000000408 R_AARCH64_IRELATIVE                       8038
 
 Symbol table '\.dynsym' contains 7 entries:
    Num:    Value          Size Type    Bind   Vis      Ndx Name
      0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
      1: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND f_base_global_default_undef
      2: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]   UND f_spec_global_default_undef
-     3: 0000000000008000     0 IFUNC   GLOBAL DEFAULT    1 f_base_global_default_ifunc
-     4: 0000000000008000     0 IFUNC   GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_ifunc
-     5: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT    1 f_base_global_default_def
-     6: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_def
+     3: 0000000000008000     0 IFUNC   GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_ifunc
+     4: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT    1 f_base_global_default_def
+     5: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_def
+     6: 0000000000008000     0 IFUNC   GLOBAL DEFAULT    1 f_base_global_default_ifunc
 
-Symbol table '\.symtab' contains 36 entries:
+Symbol table '\.symtab' contains 35 entries:
    Num:    Value          Size Type    Bind   Vis      Ndx Name
      0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
      1: 0000000000008000     0 SECTION LOCAL  DEFAULT    1 
@@ -39,30 +39,29 @@ Symbol table '\.symtab' contains 36 entries:
      6: 0000000000011120     0 SECTION LOCAL  DEFAULT    6 
      7: 00000000000111c8     0 SECTION LOCAL  DEFAULT    7 
      8: 0000000000011270     0 SECTION LOCAL  DEFAULT    8 
-     9: 00000000000112a0     0 SECTION LOCAL  DEFAULT    9 
-    10: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS .*variant_pcs-1\.o
-    11: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local
-    12: 0000000000008000     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local_ifunc
-    13: 0000000000008000     0 IFUNC   LOCAL  DEFAULT    1 f_base_local_ifunc
-    14: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT    1 f_base_local
-    15: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT    1 \$x
-    16: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS .*variant_pcs-2\.o
-    17: 0000000000008038     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local2
-    18: 0000000000008038     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local2_ifunc
-    19: 0000000000008038     0 IFUNC   LOCAL  DEFAULT    1 f_base_local2_ifunc
-    20: 0000000000008038     0 NOTYPE  LOCAL  DEFAULT    1 f_base_local2
-    21: 0000000000008038     0 NOTYPE  LOCAL  DEFAULT    1 \$x
-    22: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS 
-    23: 0000000000009080     0 OBJECT  LOCAL  DEFAULT  ABS _DYNAMIC
-    24: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_global_hidden_def
-    25: 0000000000008000     0 IFUNC   LOCAL  DEFAULT    1 f_base_global_hidden_ifunc
-    26: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT    1 f_base_global_hidden_def
-    27: 0000000000009000     0 OBJECT  LOCAL  DEFAULT  ABS _GLOBAL_OFFSET_TABLE_
-    28: 0000000000008000     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_global_hidden_ifunc
-    29: 0000000000008070     0 NOTYPE  LOCAL  DEFAULT    2 \$x
-    30: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND f_base_global_default_undef
-    31: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]   UND f_spec_global_default_undef
-    32: 0000000000008000     0 IFUNC   GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_ifunc
-    33: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT    1 f_base_global_default_def
-    34: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_def
-    35: 0000000000008000     0 IFUNC   GLOBAL DEFAULT    1 f_base_global_default_ifunc
+     9: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS .*variant_pcs-1\.o
+    10: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local
+    11: 0000000000008000     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local_ifunc
+    12: 0000000000008000     0 IFUNC   LOCAL  DEFAULT    1 f_base_local_ifunc
+    13: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT    1 f_base_local
+    14: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT    1 \$x
+    15: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS .*variant_pcs-2\.o
+    16: 0000000000008038     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local2
+    17: 0000000000008038     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local2_ifunc
+    18: 0000000000008038     0 IFUNC   LOCAL  DEFAULT    1 f_base_local2_ifunc
+    19: 0000000000008038     0 NOTYPE  LOCAL  DEFAULT    1 f_base_local2
+    20: 0000000000008038     0 NOTYPE  LOCAL  DEFAULT    1 \$x
+    21: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS 
+    22: 0000000000009080     0 OBJECT  LOCAL  DEFAULT  ABS _DYNAMIC
+    23: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_global_hidden_def
+    24: 0000000000008000     0 IFUNC   LOCAL  DEFAULT    1 f_base_global_hidden_ifunc
+    25: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT    1 f_base_global_hidden_def
+    26: 0000000000009000     0 OBJECT  LOCAL  DEFAULT  ABS _GLOBAL_OFFSET_TABLE_
+    27: 0000000000008000     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_global_hidden_ifunc
+    28: 0000000000008070     0 NOTYPE  LOCAL  DEFAULT    2 \$x
+    29: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND f_base_global_default_undef
+    30: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]   UND f_spec_global_default_undef
+    31: 0000000000008000     0 IFUNC   GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_ifunc
+    32: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT    1 f_base_global_default_def
+    33: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_def
+    34: 0000000000008000     0 IFUNC   GLOBAL DEFAULT    1 f_base_global_default_ifunc
diff --git a/ld/testsuite/ld-aarch64/variant_pcs-shared.d b/ld/testsuite/ld-aarch64/variant_pcs-shared.d
index 508bdaa206..bdcc2c867f 100644
--- a/ld/testsuite/ld-aarch64/variant_pcs-shared.d
+++ b/ld/testsuite/ld-aarch64/variant_pcs-shared.d
@@ -1,34 +1,34 @@
 #source: variant_pcs-1.s
 #source: variant_pcs-2.s
-#ld: -shared -T variant_pcs.ld
+#ld: -shared --hash-style=sysv -T variant_pcs.ld
 #readelf: -rsW
 
 Relocation section '\.rela\.plt' at offset 0x11000 contains 12 entries:
     Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
 0000000000009020  0000000100000402 R_AARCH64_JUMP_SLOT    0000000000000000 f_base_global_default_undef \+ 0
 0000000000009028  0000000200000402 R_AARCH64_JUMP_SLOT    0000000000000000 f_spec_global_default_undef \+ 0
-0000000000009030  0000000500000402 R_AARCH64_JUMP_SLOT    0000000000008000 f_base_global_default_def \+ 0
-0000000000009038  0000000600000402 R_AARCH64_JUMP_SLOT    0000000000008000 f_spec_global_default_def \+ 0
+0000000000009030  0000000400000402 R_AARCH64_JUMP_SLOT    0000000000008000 f_base_global_default_def \+ 0
+0000000000009038  0000000500000402 R_AARCH64_JUMP_SLOT    0000000000008000 f_spec_global_default_def \+ 0
 0000000000009040  0000000000000408 R_AARCH64_IRELATIVE                       8000
-0000000000009048  0000000400000402 R_AARCH64_JUMP_SLOT    f_spec_global_default_ifunc\(\) f_spec_global_default_ifunc \+ 0
+0000000000009048  0000000300000402 R_AARCH64_JUMP_SLOT    f_spec_global_default_ifunc\(\) f_spec_global_default_ifunc \+ 0
 0000000000009050  0000000000000408 R_AARCH64_IRELATIVE                       8000
-0000000000009058  0000000300000402 R_AARCH64_JUMP_SLOT    f_base_global_default_ifunc\(\) f_base_global_default_ifunc \+ 0
+0000000000009058  0000000600000402 R_AARCH64_JUMP_SLOT    f_base_global_default_ifunc\(\) f_base_global_default_ifunc \+ 0
 0000000000009060  0000000000000408 R_AARCH64_IRELATIVE                       8038
-0000000000009068  0000000000000408 R_AARCH64_IRELATIVE                       8038
+0000000000009068  0000000000000408 R_AARCH64_IRELATIVE                       8000
 0000000000009070  0000000000000408 R_AARCH64_IRELATIVE                       8000
-0000000000009078  0000000000000408 R_AARCH64_IRELATIVE                       8000
+0000000000009078  0000000000000408 R_AARCH64_IRELATIVE                       8038
 
 Symbol table '\.dynsym' contains 7 entries:
    Num:    Value          Size Type    Bind   Vis      Ndx Name
      0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
      1: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND f_base_global_default_undef
      2: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]   UND f_spec_global_default_undef
-     3: 0000000000008000     0 IFUNC   GLOBAL DEFAULT    1 f_base_global_default_ifunc
-     4: 0000000000008000     0 IFUNC   GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_ifunc
-     5: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT    1 f_base_global_default_def
-     6: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_def
+     3: 0000000000008000     0 IFUNC   GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_ifunc
+     4: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT    1 f_base_global_default_def
+     5: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_def
+     6: 0000000000008000     0 IFUNC   GLOBAL DEFAULT    1 f_base_global_default_ifunc
 
-Symbol table '\.symtab' contains 36 entries:
+Symbol table '\.symtab' contains 35 entries:
    Num:    Value          Size Type    Bind   Vis      Ndx Name
      0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
      1: 0000000000008000     0 SECTION LOCAL  DEFAULT    1 
@@ -39,30 +39,29 @@ Symbol table '\.symtab' contains 36 entries:
      6: 0000000000011120     0 SECTION LOCAL  DEFAULT    6 
      7: 00000000000111c8     0 SECTION LOCAL  DEFAULT    7 
      8: 0000000000011270     0 SECTION LOCAL  DEFAULT    8 
-     9: 00000000000112a0     0 SECTION LOCAL  DEFAULT    9 
-    10: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS .*variant_pcs-1\.o
-    11: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local
-    12: 0000000000008000     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local_ifunc
-    13: 0000000000008000     0 IFUNC   LOCAL  DEFAULT    1 f_base_local_ifunc
-    14: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT    1 f_base_local
-    15: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT    1 \$x
-    16: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS .*variant_pcs-2\.o
-    17: 0000000000008038     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local2
-    18: 0000000000008038     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local2_ifunc
-    19: 0000000000008038     0 IFUNC   LOCAL  DEFAULT    1 f_base_local2_ifunc
-    20: 0000000000008038     0 NOTYPE  LOCAL  DEFAULT    1 f_base_local2
-    21: 0000000000008038     0 NOTYPE  LOCAL  DEFAULT    1 \$x
-    22: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS 
-    23: 0000000000009080     0 OBJECT  LOCAL  DEFAULT  ABS _DYNAMIC
-    24: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_global_hidden_def
-    25: 0000000000008000     0 IFUNC   LOCAL  DEFAULT    1 f_base_global_hidden_ifunc
-    26: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT    1 f_base_global_hidden_def
-    27: 0000000000009000     0 OBJECT  LOCAL  DEFAULT  ABS _GLOBAL_OFFSET_TABLE_
-    28: 0000000000008000     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_global_hidden_ifunc
-    29: 0000000000008070     0 NOTYPE  LOCAL  DEFAULT    2 \$x
-    30: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND f_base_global_default_undef
-    31: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]   UND f_spec_global_default_undef
-    32: 0000000000008000     0 IFUNC   GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_ifunc
-    33: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT    1 f_base_global_default_def
-    34: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_def
-    35: 0000000000008000     0 IFUNC   GLOBAL DEFAULT    1 f_base_global_default_ifunc
+     9: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS .*variant_pcs-1\.o
+    10: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local
+    11: 0000000000008000     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local_ifunc
+    12: 0000000000008000     0 IFUNC   LOCAL  DEFAULT    1 f_base_local_ifunc
+    13: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT    1 f_base_local
+    14: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT    1 \$x
+    15: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS .*variant_pcs-2\.o
+    16: 0000000000008038     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local2
+    17: 0000000000008038     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local2_ifunc
+    18: 0000000000008038     0 IFUNC   LOCAL  DEFAULT    1 f_base_local2_ifunc
+    19: 0000000000008038     0 NOTYPE  LOCAL  DEFAULT    1 f_base_local2
+    20: 0000000000008038     0 NOTYPE  LOCAL  DEFAULT    1 \$x
+    21: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS 
+    22: 0000000000009080     0 OBJECT  LOCAL  DEFAULT  ABS _DYNAMIC
+    23: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_global_hidden_def
+    24: 0000000000008000     0 IFUNC   LOCAL  DEFAULT    1 f_base_global_hidden_ifunc
+    25: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT    1 f_base_global_hidden_def
+    26: 0000000000009000     0 OBJECT  LOCAL  DEFAULT  ABS _GLOBAL_OFFSET_TABLE_
+    27: 0000000000008000     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_global_hidden_ifunc
+    28: 0000000000008070     0 NOTYPE  LOCAL  DEFAULT    2 \$x
+    29: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND f_base_global_default_undef
+    30: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]   UND f_spec_global_default_undef
+    31: 0000000000008000     0 IFUNC   GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_ifunc
+    32: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT    1 f_base_global_default_def
+    33: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_def
+    34: 0000000000008000     0 IFUNC   GLOBAL DEFAULT    1 f_base_global_default_ifunc
-- 
2.17.1

Patch

diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 9e28544e4b..761e6b92b5 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -2681,6 +2681,9 @@  struct elf_aarch64_link_hash_table
   unsigned int top_index;
   asection **input_list;
 
+  /* JUMP_SLOT relocs for variant PCS symbols may be present.  */
+  int variant_pcs;
+
   /* The offset into splt of the PLT entry for the TLS descriptor
      resolver.  Special values are 0, if not necessary (or not found
      to be necessary yet), and -1 if needed but not determined
@@ -2895,6 +2898,31 @@  elfNN_aarch64_copy_indirect_symbol (struct bfd_link_info *info,
   _bfd_elf_link_hash_copy_indirect (info, dir, ind);
 }
 
+/* Merge non-visibility st_other attributes.  */
+
+static void
+elfNN_aarch64_merge_symbol_attribute (struct elf_link_hash_entry *h,
+				      const Elf_Internal_Sym *isym,
+				      bfd_boolean definition ATTRIBUTE_UNUSED,
+				      bfd_boolean dynamic ATTRIBUTE_UNUSED)
+{
+  unsigned int isym_sto = isym->st_other & ~ELF_ST_VISIBILITY (-1);
+  unsigned int h_sto = h->other & ~ELF_ST_VISIBILITY (-1);
+
+  if (isym_sto == h_sto)
+    return;
+
+  if (isym_sto & ~STO_AARCH64_VARIANT_PCS)
+    /* Not fatal, this callback cannot fail.  */
+    _bfd_error_handler (_("unknown attribute for symbol `%s': 0x%02x"),
+			h->root.root.string, isym_sto);
+
+  /* Note: Ideally we would warn about any attribute mismatch, but
+     this api does not allow that without substantial changes.  */
+  if (isym_sto & STO_AARCH64_VARIANT_PCS)
+    h->other |= STO_AARCH64_VARIANT_PCS;
+}
+
 /* Destroy an AArch64 elf linker hash table.  */
 
 static void
@@ -8571,6 +8599,12 @@  elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	     updated.  */
 
 	  htab->root.srelplt->reloc_count++;
+
+	  /* Mark the DSO in case R_<CLS>_JUMP_SLOT relocs against
+	     variant PCS symbols are present.  */
+	  if (h->other & STO_AARCH64_VARIANT_PCS)
+	    htab->variant_pcs = 1;
+
 	}
       else
 	{
@@ -9159,6 +9193,10 @@  elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 	      || !add_dynamic_entry (DT_JMPREL, 0))
 	    return FALSE;
 
+	  if (htab->variant_pcs
+	      && !add_dynamic_entry (DT_AARCH64_VARIANT_PCS, 0))
+	    return FALSE;
+
 	  if (htab->tlsdesc_plt
 	      && !(info->flags & DF_BIND_NOW)
 	      && (!add_dynamic_entry (DT_TLSDESC_PLT, 0)
@@ -10083,6 +10121,9 @@  const struct elf_size_info elfNN_aarch64_size_info =
 #define elf_backend_copy_indirect_symbol	\
   elfNN_aarch64_copy_indirect_symbol
 
+#define elf_backend_merge_symbol_attribute	\
+  elfNN_aarch64_merge_symbol_attribute
+
 /* Create .dynbss, and .rela.bss sections in DYNOBJ, and set up shortcuts
    to them in our hash.  */
 #define elf_backend_create_dynamic_sections	\
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index 1e4c38e691..c1a94957aa 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -384,6 +384,10 @@  run_dump_test "property-bti-pac3"
 run_dump_test "bti-plt-1"
 run_dump_test "bti-plt-2"
 
+run_dump_test_lp64 "variant_pcs-r"
+run_dump_test_lp64 "variant_pcs-shared"
+run_dump_test_lp64 "variant_pcs-now"
+
 set aarch64elflinktests {
   {"ld-aarch64/so with global symbol" "-shared" "" "" {copy-reloc-so.s}
     {} "copy-reloc-so.so"}
diff --git a/ld/testsuite/ld-aarch64/variant_pcs-1.s b/ld/testsuite/ld-aarch64/variant_pcs-1.s
new file mode 100644
index 0000000000..8461e8ff5e
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/variant_pcs-1.s
@@ -0,0 +1,59 @@ 
+.text
+
+.variant_pcs f_spec_global_default_def
+.variant_pcs f_spec_global_default_undef
+.variant_pcs f_spec_global_hidden_def
+.variant_pcs f_spec_local
+.variant_pcs f_spec_global_default_ifunc
+.variant_pcs f_spec_global_hidden_ifunc
+.variant_pcs f_spec_local_ifunc
+
+.global f_spec_global_default_def
+.global f_spec_global_default_undef
+.global f_spec_global_hidden_def
+.global f_spec_global_default_ifunc
+.global f_spec_global_hidden_ifunc
+.global f_base_global_default_def
+.global f_base_global_default_undef
+.global f_base_global_hidden_def
+.global f_base_global_default_ifunc
+.global f_base_global_hidden_ifunc
+
+.hidden f_spec_global_hidden_def
+.hidden f_spec_global_hidden_ifunc
+.hidden f_base_global_hidden_def
+.hidden f_base_global_hidden_ifunc
+
+.type f_spec_global_default_ifunc, %gnu_indirect_function
+.type f_spec_global_hidden_ifunc, %gnu_indirect_function
+.type f_spec_local_ifunc, %gnu_indirect_function
+.type f_base_global_default_ifunc, %gnu_indirect_function
+.type f_base_global_hidden_ifunc, %gnu_indirect_function
+.type f_base_local_ifunc, %gnu_indirect_function
+
+f_spec_global_default_def:
+f_spec_global_hidden_def:
+f_spec_local:
+f_base_global_default_def:
+f_base_global_hidden_def:
+f_base_local:
+f_spec_global_default_ifunc:
+f_spec_global_hidden_ifunc:
+f_spec_local_ifunc:
+f_base_global_default_ifunc:
+f_base_global_hidden_ifunc:
+f_base_local_ifunc:
+	bl f_spec_global_default_def
+	bl f_spec_global_default_undef
+	bl f_spec_global_hidden_def
+	bl f_spec_local
+	bl f_base_global_default_def
+	bl f_base_global_default_undef
+	bl f_base_global_hidden_def
+	bl f_base_local
+	bl f_spec_global_default_ifunc
+	bl f_spec_global_hidden_ifunc
+	bl f_spec_local_ifunc
+	bl f_base_global_default_ifunc
+	bl f_base_global_hidden_ifunc
+	bl f_base_local_ifunc
diff --git a/ld/testsuite/ld-aarch64/variant_pcs-2.s b/ld/testsuite/ld-aarch64/variant_pcs-2.s
new file mode 100644
index 0000000000..e8f13ad941
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/variant_pcs-2.s
@@ -0,0 +1,47 @@ 
+.text
+
+.variant_pcs f_spec_global_default_def
+.variant_pcs f_spec_global_default_undef
+.variant_pcs f_spec_global_hidden_def
+.variant_pcs f_spec_local2
+.variant_pcs f_spec_global_default_ifunc
+.variant_pcs f_spec_global_hidden_ifunc
+.variant_pcs f_spec_local2_ifunc
+
+.global f_spec_global_default_def
+.global f_spec_global_default_undef
+.global f_spec_global_hidden_def
+.global f_spec_global_default_ifunc
+.global f_spec_global_hidden_ifunc
+.global f_base_global_default_def
+.global f_base_global_default_undef
+.global f_base_global_hidden_def
+.global f_base_global_default_ifunc
+.global f_base_global_hidden_ifunc
+
+.hidden f_spec_global_hidden_def
+.hidden f_spec_global_hidden_ifunc
+.hidden f_base_global_hidden_def
+.hidden f_base_global_hidden_ifunc
+
+.type f_spec_local2_ifunc, %gnu_indirect_function
+.type f_base_local2_ifunc, %gnu_indirect_function
+
+f_spec_local2:
+f_base_local2:
+f_spec_local2_ifunc:
+f_base_local2_ifunc:
+	bl f_spec_global_default_def
+	bl f_spec_global_default_undef
+	bl f_spec_global_hidden_def
+	bl f_spec_local2
+	bl f_base_global_default_def
+	bl f_base_global_default_undef
+	bl f_base_global_hidden_def
+	bl f_base_local2
+	bl f_spec_global_default_ifunc
+	bl f_spec_global_hidden_ifunc
+	bl f_spec_local2_ifunc
+	bl f_base_global_default_ifunc
+	bl f_base_global_hidden_ifunc
+	bl f_base_local2_ifunc
diff --git a/ld/testsuite/ld-aarch64/variant_pcs-now.d b/ld/testsuite/ld-aarch64/variant_pcs-now.d
new file mode 100644
index 0000000000..fc238929da
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/variant_pcs-now.d
@@ -0,0 +1,68 @@ 
+#source: variant_pcs-1.s
+#source: variant_pcs-2.s
+#ld: -shared -T variant_pcs.ld -z now
+#readelf: -rsW
+
+Relocation section '\.rela\.plt' at offset 0x11000 contains 12 entries:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0000000000009020  0000000100000402 R_AARCH64_JUMP_SLOT    0000000000000000 f_base_global_default_undef \+ 0
+0000000000009028  0000000200000402 R_AARCH64_JUMP_SLOT    0000000000000000 f_spec_global_default_undef \+ 0
+0000000000009030  0000000500000402 R_AARCH64_JUMP_SLOT    0000000000008000 f_base_global_default_def \+ 0
+0000000000009038  0000000600000402 R_AARCH64_JUMP_SLOT    0000000000008000 f_spec_global_default_def \+ 0
+0000000000009040  0000000000000408 R_AARCH64_IRELATIVE                       8000
+0000000000009048  0000000400000402 R_AARCH64_JUMP_SLOT    f_spec_global_default_ifunc\(\) f_spec_global_default_ifunc \+ 0
+0000000000009050  0000000000000408 R_AARCH64_IRELATIVE                       8000
+0000000000009058  0000000300000402 R_AARCH64_JUMP_SLOT    f_base_global_default_ifunc\(\) f_base_global_default_ifunc \+ 0
+0000000000009060  0000000000000408 R_AARCH64_IRELATIVE                       8038
+0000000000009068  0000000000000408 R_AARCH64_IRELATIVE                       8038
+0000000000009070  0000000000000408 R_AARCH64_IRELATIVE                       8000
+0000000000009078  0000000000000408 R_AARCH64_IRELATIVE                       8000
+
+Symbol table '\.dynsym' contains 7 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND f_base_global_default_undef
+     2: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]   UND f_spec_global_default_undef
+     3: 0000000000008000     0 IFUNC   GLOBAL DEFAULT    1 f_base_global_default_ifunc
+     4: 0000000000008000     0 IFUNC   GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_ifunc
+     5: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT    1 f_base_global_default_def
+     6: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_def
+
+Symbol table '\.symtab' contains 36 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 0000000000008000     0 SECTION LOCAL  DEFAULT    1 
+     2: 0000000000008070     0 SECTION LOCAL  DEFAULT    2 
+     3: 0000000000009000     0 SECTION LOCAL  DEFAULT    3 
+     4: 0000000000009080     0 SECTION LOCAL  DEFAULT    4 
+     5: 0000000000011000     0 SECTION LOCAL  DEFAULT    5 
+     6: 0000000000011120     0 SECTION LOCAL  DEFAULT    6 
+     7: 00000000000111c8     0 SECTION LOCAL  DEFAULT    7 
+     8: 0000000000011270     0 SECTION LOCAL  DEFAULT    8 
+     9: 00000000000112a0     0 SECTION LOCAL  DEFAULT    9 
+    10: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS .*variant_pcs-1\.o
+    11: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local
+    12: 0000000000008000     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local_ifunc
+    13: 0000000000008000     0 IFUNC   LOCAL  DEFAULT    1 f_base_local_ifunc
+    14: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT    1 f_base_local
+    15: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT    1 \$x
+    16: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS .*variant_pcs-2\.o
+    17: 0000000000008038     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local2
+    18: 0000000000008038     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local2_ifunc
+    19: 0000000000008038     0 IFUNC   LOCAL  DEFAULT    1 f_base_local2_ifunc
+    20: 0000000000008038     0 NOTYPE  LOCAL  DEFAULT    1 f_base_local2
+    21: 0000000000008038     0 NOTYPE  LOCAL  DEFAULT    1 \$x
+    22: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS 
+    23: 0000000000009080     0 OBJECT  LOCAL  DEFAULT  ABS _DYNAMIC
+    24: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_global_hidden_def
+    25: 0000000000008000     0 IFUNC   LOCAL  DEFAULT    1 f_base_global_hidden_ifunc
+    26: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT    1 f_base_global_hidden_def
+    27: 0000000000009000     0 OBJECT  LOCAL  DEFAULT  ABS _GLOBAL_OFFSET_TABLE_
+    28: 0000000000008000     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_global_hidden_ifunc
+    29: 0000000000008070     0 NOTYPE  LOCAL  DEFAULT    2 \$x
+    30: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND f_base_global_default_undef
+    31: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]   UND f_spec_global_default_undef
+    32: 0000000000008000     0 IFUNC   GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_ifunc
+    33: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT    1 f_base_global_default_def
+    34: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_def
+    35: 0000000000008000     0 IFUNC   GLOBAL DEFAULT    1 f_base_global_default_ifunc
diff --git a/ld/testsuite/ld-aarch64/variant_pcs-r.d b/ld/testsuite/ld-aarch64/variant_pcs-r.d
new file mode 100644
index 0000000000..a534149d9e
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/variant_pcs-r.d
@@ -0,0 +1,60 @@ 
+#source: variant_pcs-1.s
+#source: variant_pcs-2.s
+#ld: -r
+#readelf: -rsW
+
+Relocation section '\.rela\.text' at offset .* contains 24 entries:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0000000000000000  000000180000011b R_AARCH64_CALL26       0000000000000000 f_spec_global_default_def \+ 0
+0000000000000004  000000110000011b R_AARCH64_CALL26       0000000000000000 f_spec_global_default_undef \+ 0
+0000000000000008  000000120000011b R_AARCH64_CALL26       0000000000000000 f_spec_global_hidden_def \+ 0
+0000000000000010  000000170000011b R_AARCH64_CALL26       0000000000000000 f_base_global_default_def \+ 0
+0000000000000014  000000100000011b R_AARCH64_CALL26       0000000000000000 f_base_global_default_undef \+ 0
+0000000000000018  000000150000011b R_AARCH64_CALL26       0000000000000000 f_base_global_hidden_def \+ 0
+0000000000000020  000000140000011b R_AARCH64_CALL26       f_spec_global_default_ifunc\(\) f_spec_global_default_ifunc \+ 0
+0000000000000024  000000160000011b R_AARCH64_CALL26       f_spec_global_hidden_ifunc\(\) f_spec_global_hidden_ifunc \+ 0
+0000000000000028  000000060000011b R_AARCH64_CALL26       f_spec_local_ifunc\(\) f_spec_local_ifunc \+ 0
+000000000000002c  000000190000011b R_AARCH64_CALL26       f_base_global_default_ifunc\(\) f_base_global_default_ifunc \+ 0
+0000000000000030  000000130000011b R_AARCH64_CALL26       f_base_global_hidden_ifunc\(\) f_base_global_hidden_ifunc \+ 0
+0000000000000034  000000070000011b R_AARCH64_CALL26       f_base_local_ifunc\(\) f_base_local_ifunc \+ 0
+0000000000000038  000000180000011b R_AARCH64_CALL26       0000000000000000 f_spec_global_default_def \+ 0
+000000000000003c  000000110000011b R_AARCH64_CALL26       0000000000000000 f_spec_global_default_undef \+ 0
+0000000000000040  000000120000011b R_AARCH64_CALL26       0000000000000000 f_spec_global_hidden_def \+ 0
+0000000000000048  000000170000011b R_AARCH64_CALL26       0000000000000000 f_base_global_default_def \+ 0
+000000000000004c  000000100000011b R_AARCH64_CALL26       0000000000000000 f_base_global_default_undef \+ 0
+0000000000000050  000000150000011b R_AARCH64_CALL26       0000000000000000 f_base_global_hidden_def \+ 0
+0000000000000058  000000140000011b R_AARCH64_CALL26       f_spec_global_default_ifunc\(\) f_spec_global_default_ifunc \+ 0
+000000000000005c  000000160000011b R_AARCH64_CALL26       f_spec_global_hidden_ifunc\(\) f_spec_global_hidden_ifunc \+ 0
+0000000000000060  0000000c0000011b R_AARCH64_CALL26       f_spec_local2_ifunc\(\) f_spec_local2_ifunc \+ 0
+0000000000000064  000000190000011b R_AARCH64_CALL26       f_base_global_default_ifunc\(\) f_base_global_default_ifunc \+ 0
+0000000000000068  000000130000011b R_AARCH64_CALL26       f_base_global_hidden_ifunc\(\) f_base_global_hidden_ifunc \+ 0
+000000000000006c  0000000d0000011b R_AARCH64_CALL26       f_base_local2_ifunc\(\) f_base_local2_ifunc \+ 0
+
+Symbol table '\.symtab' contains 26 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
+     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
+     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
+     4: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS .*variant_pcs-1\.o
+     5: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local
+     6: 0000000000000000     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local_ifunc
+     7: 0000000000000000     0 IFUNC   LOCAL  DEFAULT    1 f_base_local_ifunc
+     8: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT    1 f_base_local
+     9: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT    1 \$x
+    10: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS .*variant_pcs-2\.o
+    11: 0000000000000038     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local2
+    12: 0000000000000038     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local2_ifunc
+    13: 0000000000000038     0 IFUNC   LOCAL  DEFAULT    1 f_base_local2_ifunc
+    14: 0000000000000038     0 NOTYPE  LOCAL  DEFAULT    1 f_base_local2
+    15: 0000000000000038     0 NOTYPE  LOCAL  DEFAULT    1 \$x
+    16: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND f_base_global_default_undef
+    17: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]   UND f_spec_global_default_undef
+    18: 0000000000000000     0 NOTYPE  GLOBAL HIDDEN  \[VARIANT_PCS\]     1 f_spec_global_hidden_def
+    19: 0000000000000000     0 IFUNC   GLOBAL HIDDEN     1 f_base_global_hidden_ifunc
+    20: 0000000000000000     0 IFUNC   GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_ifunc
+    21: 0000000000000000     0 NOTYPE  GLOBAL HIDDEN     1 f_base_global_hidden_def
+    22: 0000000000000000     0 IFUNC   GLOBAL HIDDEN  \[VARIANT_PCS\]     1 f_spec_global_hidden_ifunc
+    23: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT    1 f_base_global_default_def
+    24: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_def
+    25: 0000000000000000     0 IFUNC   GLOBAL DEFAULT    1 f_base_global_default_ifunc
diff --git a/ld/testsuite/ld-aarch64/variant_pcs-shared.d b/ld/testsuite/ld-aarch64/variant_pcs-shared.d
new file mode 100644
index 0000000000..508bdaa206
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/variant_pcs-shared.d
@@ -0,0 +1,68 @@ 
+#source: variant_pcs-1.s
+#source: variant_pcs-2.s
+#ld: -shared -T variant_pcs.ld
+#readelf: -rsW
+
+Relocation section '\.rela\.plt' at offset 0x11000 contains 12 entries:
+    Offset             Info             Type               Symbol's Value  Symbol's Name \+ Addend
+0000000000009020  0000000100000402 R_AARCH64_JUMP_SLOT    0000000000000000 f_base_global_default_undef \+ 0
+0000000000009028  0000000200000402 R_AARCH64_JUMP_SLOT    0000000000000000 f_spec_global_default_undef \+ 0
+0000000000009030  0000000500000402 R_AARCH64_JUMP_SLOT    0000000000008000 f_base_global_default_def \+ 0
+0000000000009038  0000000600000402 R_AARCH64_JUMP_SLOT    0000000000008000 f_spec_global_default_def \+ 0
+0000000000009040  0000000000000408 R_AARCH64_IRELATIVE                       8000
+0000000000009048  0000000400000402 R_AARCH64_JUMP_SLOT    f_spec_global_default_ifunc\(\) f_spec_global_default_ifunc \+ 0
+0000000000009050  0000000000000408 R_AARCH64_IRELATIVE                       8000
+0000000000009058  0000000300000402 R_AARCH64_JUMP_SLOT    f_base_global_default_ifunc\(\) f_base_global_default_ifunc \+ 0
+0000000000009060  0000000000000408 R_AARCH64_IRELATIVE                       8038
+0000000000009068  0000000000000408 R_AARCH64_IRELATIVE                       8038
+0000000000009070  0000000000000408 R_AARCH64_IRELATIVE                       8000
+0000000000009078  0000000000000408 R_AARCH64_IRELATIVE                       8000
+
+Symbol table '\.dynsym' contains 7 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND f_base_global_default_undef
+     2: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]   UND f_spec_global_default_undef
+     3: 0000000000008000     0 IFUNC   GLOBAL DEFAULT    1 f_base_global_default_ifunc
+     4: 0000000000008000     0 IFUNC   GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_ifunc
+     5: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT    1 f_base_global_default_def
+     6: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_def
+
+Symbol table '\.symtab' contains 36 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 0000000000008000     0 SECTION LOCAL  DEFAULT    1 
+     2: 0000000000008070     0 SECTION LOCAL  DEFAULT    2 
+     3: 0000000000009000     0 SECTION LOCAL  DEFAULT    3 
+     4: 0000000000009080     0 SECTION LOCAL  DEFAULT    4 
+     5: 0000000000011000     0 SECTION LOCAL  DEFAULT    5 
+     6: 0000000000011120     0 SECTION LOCAL  DEFAULT    6 
+     7: 00000000000111c8     0 SECTION LOCAL  DEFAULT    7 
+     8: 0000000000011270     0 SECTION LOCAL  DEFAULT    8 
+     9: 00000000000112a0     0 SECTION LOCAL  DEFAULT    9 
+    10: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS .*variant_pcs-1\.o
+    11: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local
+    12: 0000000000008000     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local_ifunc
+    13: 0000000000008000     0 IFUNC   LOCAL  DEFAULT    1 f_base_local_ifunc
+    14: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT    1 f_base_local
+    15: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT    1 \$x
+    16: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS .*variant_pcs-2\.o
+    17: 0000000000008038     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local2
+    18: 0000000000008038     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_local2_ifunc
+    19: 0000000000008038     0 IFUNC   LOCAL  DEFAULT    1 f_base_local2_ifunc
+    20: 0000000000008038     0 NOTYPE  LOCAL  DEFAULT    1 f_base_local2
+    21: 0000000000008038     0 NOTYPE  LOCAL  DEFAULT    1 \$x
+    22: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS 
+    23: 0000000000009080     0 OBJECT  LOCAL  DEFAULT  ABS _DYNAMIC
+    24: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_global_hidden_def
+    25: 0000000000008000     0 IFUNC   LOCAL  DEFAULT    1 f_base_global_hidden_ifunc
+    26: 0000000000008000     0 NOTYPE  LOCAL  DEFAULT    1 f_base_global_hidden_def
+    27: 0000000000009000     0 OBJECT  LOCAL  DEFAULT  ABS _GLOBAL_OFFSET_TABLE_
+    28: 0000000000008000     0 IFUNC   LOCAL  DEFAULT \[VARIANT_PCS\]     1 f_spec_global_hidden_ifunc
+    29: 0000000000008070     0 NOTYPE  LOCAL  DEFAULT    2 \$x
+    30: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND f_base_global_default_undef
+    31: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]   UND f_spec_global_default_undef
+    32: 0000000000008000     0 IFUNC   GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_ifunc
+    33: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT    1 f_base_global_default_def
+    34: 0000000000008000     0 NOTYPE  GLOBAL DEFAULT \[VARIANT_PCS\]     1 f_spec_global_default_def
+    35: 0000000000008000     0 IFUNC   GLOBAL DEFAULT    1 f_base_global_default_ifunc
diff --git a/ld/testsuite/ld-aarch64/variant_pcs.ld b/ld/testsuite/ld-aarch64/variant_pcs.ld
new file mode 100644
index 0000000000..a66a9343a7
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/variant_pcs.ld
@@ -0,0 +1,23 @@ 
+/* Script for .variant_pcs symbol tests.  */
+OUTPUT_ARCH(aarch64)
+ENTRY(_start)
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  PROVIDE (__executable_start = 0x8000); . = 0x8000;
+  .text           :
+  {
+    *(.before)
+    *(.text)
+    *(.after)
+  } =0
+  . = 0x9000;
+  .got            : { *(.got) *(.got.plt)}
+  . = 0x10000;
+  .rela.dyn       : { *(.rela.ifunc) }
+  . = 0x11000;
+  .rela.plt       : { *(.rela.plt) *(.rela.iplt) }
+  . = 0x12340000;
+  .far : { *(.far) }
+  .ARM.attributes 0 : { *(.ARM.atttributes) }
+}