aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
Diffstat (limited to 'ld')
-rw-r--r--ld/NEWS3
-rw-r--r--ld/emulparams/extern_protected_data.sh10
-rw-r--r--ld/ld.texi12
-rw-r--r--ld/ldmain.c1
-rw-r--r--ld/testsuite/ld-elf/indirect-extern-access-1.rd8
-rw-r--r--ld/testsuite/ld-elf/indirect-extern-access-1a.c1
-rw-r--r--ld/testsuite/ld-elf/indirect-extern-access-1b.c12
-rw-r--r--ld/testsuite/ld-elf/indirect-extern-access-2.rd8
-rw-r--r--ld/testsuite/ld-elf/indirect-extern-access-2a.c10
-rw-r--r--ld/testsuite/ld-elf/indirect-extern-access-2b.c13
-rw-r--r--ld/testsuite/ld-elf/indirect-extern-access-3.rd8
-rw-r--r--ld/testsuite/ld-elf/indirect-extern-access.S20
-rw-r--r--ld/testsuite/ld-elf/linux-x86.exp97
-rw-r--r--ld/testsuite/ld-elf/property-1_needed-1b.d16
-rw-r--r--ld/testsuite/ld-elf/property-1_needed-1c.d17
-rw-r--r--ld/testsuite/ld-x86-64/indirect-extern-access.rd6
-rw-r--r--ld/testsuite/ld-x86-64/protected-data-1.h11
-rw-r--r--ld/testsuite/ld-x86-64/protected-data-1a.c40
-rw-r--r--ld/testsuite/ld-x86-64/protected-data-1b.c59
-rw-r--r--ld/testsuite/ld-x86-64/protected-data-2a.S109
-rw-r--r--ld/testsuite/ld-x86-64/protected-data-2b.S119
-rw-r--r--ld/testsuite/ld-x86-64/protected-func-2a.S68
-rw-r--r--ld/testsuite/ld-x86-64/protected-func-2b.S83
-rw-r--r--ld/testsuite/ld-x86-64/protected-func-2c.c29
-rw-r--r--ld/testsuite/ld-x86-64/x86-64.exp147
25 files changed, 907 insertions, 0 deletions
diff --git a/ld/NEWS b/ld/NEWS
index 92dd4fd..59d1d3c 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,8 @@
-*- text -*-
+* Add -z indirect-extern-access/-z noindirect-extern-access to control
+ canonical function pointers and copy relocation.
+
* Add --max-cache-size=SIZE to set the the maximum cache size to SIZE
bytes.
diff --git a/ld/emulparams/extern_protected_data.sh b/ld/emulparams/extern_protected_data.sh
index 30f3d1c..cb855a6 100644
--- a/ld/emulparams/extern_protected_data.sh
+++ b/ld/emulparams/extern_protected_data.sh
@@ -1,11 +1,21 @@
PARSE_AND_LIST_OPTIONS_NOEXTEN_PROTECTED_DATA='
fprintf (file, _("\
-z noextern-protected-data Do not treat protected data symbol as external\n"));
+ fprintf (file, _("\
+ -z indirect-extern-access Enable indirect external access\n"));
+ fprintf (file, _("\
+ -z noindirect-extern-access Disable indirect external access (default)\n"));
'
+# Set link_info.indirect_extern_access to 2 to indicate that it is set
+# by "-z indirect-extern-access".
PARSE_AND_LIST_ARGS_CASE_Z_NOEXTEN_PROTECTED_DATA='
else if (strcmp (optarg, "noextern-protected-data") == 0)
link_info.extern_protected_data = false;
+ else if (strcmp (optarg, "indirect-extern-access") == 0)
+ link_info.indirect_extern_access = 2;
+ else if (strcmp (optarg, "noindirect-extern-access") == 0)
+ link_info.indirect_extern_access = 0;
'
diff --git a/ld/ld.texi b/ld/ld.texi
index 67c5083..b6d8dcc 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -1293,6 +1293,18 @@ Generate GNU_PROPERTY_X86_FEATURE_1_IBT in .note.gnu.property section
to indicate compatibility with IBT. This also implies @option{ibtplt}.
Supported for Linux/i386 and Linux/x86_64.
+@item indirect-extern-access
+@itemx noindirect-extern-access
+Generate GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS in
+.note.gnu.property section to indicate that object file requires
+canonical function pointers and cannot be used with copy relocation.
+This option also implies @option{noextern-protected-data} and
+@option{nocopyreloc}. Supported for i386 and x86-64.
+
+@option{noindirect-extern-access} removes
+GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS from .note.gnu.property
+section.
+
@item initfirst
This option is only meaningful when building a shared object.
It marks the object so that its runtime initialization will occur
diff --git a/ld/ldmain.c b/ld/ldmain.c
index e4c6774..0202923 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -347,6 +347,7 @@ main (int argc, char **argv)
link_info.relax_pass = 1;
link_info.extern_protected_data = -1;
link_info.dynamic_undefined_weak = -1;
+ link_info.indirect_extern_access = -1;
link_info.pei386_auto_import = -1;
link_info.spare_dynamic_tags = 5;
link_info.path_separator = ':';
diff --git a/ld/testsuite/ld-elf/indirect-extern-access-1.rd b/ld/testsuite/ld-elf/indirect-extern-access-1.rd
new file mode 100644
index 0000000..39dc89a
--- /dev/null
+++ b/ld/testsuite/ld-elf/indirect-extern-access-1.rd
@@ -0,0 +1,8 @@
+#...
+[a-f0-9]+ +[0-9a-f]+ +R_.*_COPY +[a-f0-9]+ +indirect_extern_access( \+ 0|)
+#...
+Displaying notes found in: .note.gnu.property
+[ ]+Owner[ ]+Data size[ ]+Description
+ GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0
+ Properties: 1_needed:
+#pass
diff --git a/ld/testsuite/ld-elf/indirect-extern-access-1a.c b/ld/testsuite/ld-elf/indirect-extern-access-1a.c
new file mode 100644
index 0000000..4789810
--- /dev/null
+++ b/ld/testsuite/ld-elf/indirect-extern-access-1a.c
@@ -0,0 +1 @@
+int indirect_extern_access = 1;
diff --git a/ld/testsuite/ld-elf/indirect-extern-access-1b.c b/ld/testsuite/ld-elf/indirect-extern-access-1b.c
new file mode 100644
index 0000000..68adae5
--- /dev/null
+++ b/ld/testsuite/ld-elf/indirect-extern-access-1b.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+extern int indirect_extern_access;
+
+int
+main (void)
+{
+ if (indirect_extern_access == 1)
+ puts ("PASS");
+
+ return 0;
+}
diff --git a/ld/testsuite/ld-elf/indirect-extern-access-2.rd b/ld/testsuite/ld-elf/indirect-extern-access-2.rd
new file mode 100644
index 0000000..9c7d72f
--- /dev/null
+++ b/ld/testsuite/ld-elf/indirect-extern-access-2.rd
@@ -0,0 +1,8 @@
+#...
+[a-f0-9]+ +[0-9a-f]+ +R_.*_JUMP_SLO(T|) +[a-f0-9]+ +indirect_extern_access( \+ 0|)
+#...
+Displaying notes found in: .note.gnu.property
+[ ]+Owner[ ]+Data size[ ]+Description
+ GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0
+ Properties: 1_needed:
+#pass
diff --git a/ld/testsuite/ld-elf/indirect-extern-access-2a.c b/ld/testsuite/ld-elf/indirect-extern-access-2a.c
new file mode 100644
index 0000000..cb57068
--- /dev/null
+++ b/ld/testsuite/ld-elf/indirect-extern-access-2a.c
@@ -0,0 +1,10 @@
+void
+indirect_extern_access (void)
+{
+}
+
+void *
+indirect_extern_access_p (void)
+{
+ return indirect_extern_access;
+}
diff --git a/ld/testsuite/ld-elf/indirect-extern-access-2b.c b/ld/testsuite/ld-elf/indirect-extern-access-2b.c
new file mode 100644
index 0000000..dedfd9b
--- /dev/null
+++ b/ld/testsuite/ld-elf/indirect-extern-access-2b.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+
+extern void indirect_extern_access (void);
+extern void *indirect_extern_access_p (void);
+
+int
+main (void)
+{
+ if (&indirect_extern_access == indirect_extern_access_p ())
+ puts ("PASS");
+
+ return 0;
+}
diff --git a/ld/testsuite/ld-elf/indirect-extern-access-3.rd b/ld/testsuite/ld-elf/indirect-extern-access-3.rd
new file mode 100644
index 0000000..ce777a5
--- /dev/null
+++ b/ld/testsuite/ld-elf/indirect-extern-access-3.rd
@@ -0,0 +1,8 @@
+#...
+[a-f0-9]+ +[0-9a-f]+ +R_.*_GLOB_DAT +[a-f0-9]+ +indirect_extern_access( \+ 0|)
+#...
+Displaying notes found in: .note.gnu.property
+[ ]+Owner[ ]+Data size[ ]+Description
+ GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0
+ Properties: 1_needed: indirect external access
+#pass
diff --git a/ld/testsuite/ld-elf/indirect-extern-access.S b/ld/testsuite/ld-elf/indirect-extern-access.S
new file mode 100644
index 0000000..25b88ba
--- /dev/null
+++ b/ld/testsuite/ld-elf/indirect-extern-access.S
@@ -0,0 +1,20 @@
+# ifdef __LP64__
+# define ALIGN 3
+# else
+# define ALIGN 2
+# endif
+ .section ".note.gnu.property", "a"
+ .p2align ALIGN
+ .long 1f - 0f /* name length */
+ .long 5f - 2f /* data length */
+ .long 5 /* note type */
+0: .asciz "GNU" /* vendor name */
+1:
+ .p2align ALIGN
+2: .long 0xb0008000 /* pr_type. */
+ .long 4f - 3f /* pr_datasz. */
+3:
+ .long 0x1
+4:
+ .p2align ALIGN
+5:
diff --git a/ld/testsuite/ld-elf/linux-x86.exp b/ld/testsuite/ld-elf/linux-x86.exp
index 7e3a0b7..8192374 100644
--- a/ld/testsuite/ld-elf/linux-x86.exp
+++ b/ld/testsuite/ld-elf/linux-x86.exp
@@ -73,6 +73,103 @@ run_ld_link_tests [list \
] \
]
+run_cc_link_tests [list \
+ [list \
+ "Build indirect-extern-access-1.so" \
+ "-shared" \
+ "-fPIC" \
+ { indirect-extern-access-1a.c } \
+ {} \
+ "indirect-extern-access-1.so" \
+ ] \
+ [list \
+ "Build indirect-extern-access-1a without PIE" \
+ "$NOPIE_LDFLAGS -Wl,--no-as-needed \
+ tmpdir/indirect-extern-access-1.so" \
+ "$NOPIE_CFLAGS" \
+ { indirect-extern-access.S indirect-extern-access-1b.c } \
+ {{readelf -rn indirect-extern-access-1.rd}} \
+ "indirect-extern-access-1a" \
+ ] \
+ [list \
+ "Build indirect-extern-access-2.so" \
+ "-shared" \
+ "-fPIC" \
+ { indirect-extern-access-2a.c } \
+ {} \
+ "indirect-extern-access-2.so" \
+ ] \
+ [list \
+ "Build indirect-extern-access-2a without PIE" \
+ "$NOPIE_LDFLAGS -Wl,--no-as-needed \
+ tmpdir/indirect-extern-access-2.so" \
+ "$NOPIE_CFLAGS" \
+ { indirect-extern-access.S indirect-extern-access-1b.c } \
+ {{readelf -rn indirect-extern-access-2.rd}} \
+ "indirect-extern-access-2a" \
+ ] \
+ [list \
+ "Build indirect-extern-access-2b with PIE" \
+ "-pie -Wl,--no-as-needed \
+ tmpdir/indirect-extern-access-2.so" \
+ "-fpie" \
+ { indirect-extern-access.S indirect-extern-access-2b.c } \
+ {{readelf -rn indirect-extern-access-3.rd}} \
+ "indirect-extern-access-2b" \
+ ] \
+]
+
+run_ld_link_exec_tests [list \
+ [list \
+ "Run indirect-extern-access-1a without PIE" \
+ "$NOPIE_LDFLAGS" \
+ "" \
+ { indirect-extern-access.S indirect-extern-access-1b.c } \
+ "indirect-extern-access-1a" \
+ "pass.out" \
+ "$NOPIE_CFLAGS" \
+ "" \
+ "" \
+ "tmpdir/indirect-extern-access-1.so" \
+ ] \
+ [list \
+ "Run indirect-extern-access-1b with PIE" \
+ "-pie" \
+ "" \
+ { indirect-extern-access.S indirect-extern-access-1b.c } \
+ "indirect-extern-access-1b" \
+ "pass.out" \
+ "-fpie" \
+ "" \
+ "" \
+ "tmpdir/indirect-extern-access-1.so" \
+ ] \
+ [list \
+ "Run indirect-extern-access-2a without PIE" \
+ "$NOPIE_LDFLAGS" \
+ "" \
+ { indirect-extern-access.S indirect-extern-access-2b.c } \
+ "indirect-extern-access-2a" \
+ "pass.out" \
+ "$NOPIE_CFLAGS" \
+ "" \
+ "" \
+ "tmpdir/indirect-extern-access-2.so" \
+ ] \
+ [list \
+ "Run indirect-extern-access-2b with PIE" \
+ "-pie" \
+ "" \
+ { indirect-extern-access.S indirect-extern-access-2b.c } \
+ "indirect-extern-access-2b" \
+ "pass.out" \
+ "-fpie" \
+ "" \
+ "" \
+ "tmpdir/indirect-extern-access-2.so" \
+ ] \
+]
+
proc elfedit_test { options test output } {
global ELFEDIT
global READELF
diff --git a/ld/testsuite/ld-elf/property-1_needed-1b.d b/ld/testsuite/ld-elf/property-1_needed-1b.d
new file mode 100644
index 0000000..b7a9eea
--- /dev/null
+++ b/ld/testsuite/ld-elf/property-1_needed-1b.d
@@ -0,0 +1,16 @@
+#source: empty.s
+#as:
+#ld: -shared -z indirect-extern-access
+#readelf: -n
+#xfail: ![check_shared_lib_support]
+#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-*
+# Assembly source file for the HPPA assembler is renamed and modifed by
+# sed. mn10300 has relocations in .note.gnu.property section which
+# elf_parse_notes doesn't support.
+
+#...
+Displaying notes found in: .note.gnu.property
+[ ]+Owner[ ]+Data size[ ]+Description
+ GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0
+ Properties: 1_needed: indirect external access
+#pass
diff --git a/ld/testsuite/ld-elf/property-1_needed-1c.d b/ld/testsuite/ld-elf/property-1_needed-1c.d
new file mode 100644
index 0000000..21e1d26
--- /dev/null
+++ b/ld/testsuite/ld-elf/property-1_needed-1c.d
@@ -0,0 +1,17 @@
+#source: empty.s
+#source: property-1_needed-1.s
+#as:
+#ld: -shared -z noindirect-extern-access
+#readelf: -n
+#xfail: ![check_shared_lib_support]
+#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-*
+# Assembly source file for the HPPA assembler is renamed and modifed by
+# sed. mn10300 has relocations in .note.gnu.property section which
+# elf_parse_notes doesn't support.
+
+#...
+Displaying notes found in: .note.gnu.property
+[ ]+Owner[ ]+Data size[ ]+Description
+ GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0
+ Properties: 1_needed: <unknown: 2>
+#pass
diff --git a/ld/testsuite/ld-x86-64/indirect-extern-access.rd b/ld/testsuite/ld-x86-64/indirect-extern-access.rd
new file mode 100644
index 0000000..696b06f
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/indirect-extern-access.rd
@@ -0,0 +1,6 @@
+#...
+Displaying notes found in: .note.gnu.property
+[ ]+Owner[ ]+Data size[ ]+Description
+ GNU 0x[0-9a-f]+ NT_GNU_PROPERTY_TYPE_0
+ Properties: 1_needed: indirect external access
+#pass
diff --git a/ld/testsuite/ld-x86-64/protected-data-1.h b/ld/testsuite/ld-x86-64/protected-data-1.h
new file mode 100644
index 0000000..a80c976
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/protected-data-1.h
@@ -0,0 +1,11 @@
+extern int protected_data_1a;
+extern int protected_data_1b;
+
+extern int *protected_data_1a_p ();
+extern int *protected_data_1b_p ();
+
+extern void set_protected_data_1a (int);
+extern void set_protected_data_1b (int);
+
+extern int check_protected_data_1a (int);
+extern int check_protected_data_1b (int);
diff --git a/ld/testsuite/ld-x86-64/protected-data-1a.c b/ld/testsuite/ld-x86-64/protected-data-1a.c
new file mode 100644
index 0000000..6942426
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/protected-data-1a.c
@@ -0,0 +1,40 @@
+#include "protected-data-1.h"
+
+int protected_data_1a __attribute__ ((visibility("protected"))) = 1;
+int protected_data_1b __attribute__ ((visibility("protected"))) = 2;
+
+int *
+protected_data_1a_p (void)
+{
+ return &protected_data_1a;
+}
+
+int *
+protected_data_1b_p (void)
+{
+ return &protected_data_1b;
+}
+
+void
+set_protected_data_1a (int i)
+{
+ protected_data_1a = i;
+}
+
+void
+set_protected_data_1b (int i)
+{
+ protected_data_1b = i;
+}
+
+int
+check_protected_data_1a (int i)
+{
+ return protected_data_1a == i ? 0 : 1;
+}
+
+int
+check_protected_data_1b (int i)
+{
+ return protected_data_1b == i ? 0 : 1;
+}
diff --git a/ld/testsuite/ld-x86-64/protected-data-1b.c b/ld/testsuite/ld-x86-64/protected-data-1b.c
new file mode 100644
index 0000000..a4756ee
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/protected-data-1b.c
@@ -0,0 +1,59 @@
+#include <stdio.h>
+
+#include "protected-data-1.h"
+
+int protected_data_1b = 3;
+
+int
+main (void)
+{
+ int res = 0;
+
+ /* Check if we get the same address for the protected data symbol. */
+ if (&protected_data_1a != protected_data_1a_p ())
+ {
+ puts ("'protected_data_1a' in main and shared library doesn't have same address");
+ res = 1;
+ }
+
+ protected_data_1a = -1;
+ if (check_protected_data_1a (-1))
+ {
+ puts ("'protected_data_1a' in main and shared library doesn't have same value");
+ res = 1;
+ }
+
+ set_protected_data_1a (-3);
+ if (protected_data_1a != -3)
+ {
+ puts ("'protected_data_1a' in main and shared library doesn't have same value");
+ res = 1;
+ }
+
+ /* Check if we get the different addresses for the protected data
+ symbol. */
+ if (&protected_data_1b == protected_data_1b_p ())
+ {
+ puts ("'protected_data_1b' in main and shared library has same address");
+ res = 1;
+ }
+
+ protected_data_1b = -10;
+ if (check_protected_data_1b (2))
+ {
+ puts ("'protected_data_1b' in main and shared library has same address");
+ res = 1;
+ }
+
+ set_protected_data_1b (-30);
+ if (protected_data_1b != -10)
+ {
+ puts ("'protected_data_1b' in main and shared library has same address");
+ res = 1;
+ }
+
+ if (!res)
+ puts ("PASS");
+
+ return res;
+}
diff --git a/ld/testsuite/ld-x86-64/protected-data-2a.S b/ld/testsuite/ld-x86-64/protected-data-2a.S
new file mode 100644
index 0000000..865c1af
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/protected-data-2a.S
@@ -0,0 +1,109 @@
+ .text
+ .p2align 4
+ .protected protected_data_1a
+ .globl protected_data_1a_p
+ .type protected_data_1a_p, @function
+protected_data_1a_p:
+.LFB0:
+ .cfi_startproc
+ leaq protected_data_1a(%rip), %rax
+ ret
+ .cfi_endproc
+.LFE0:
+ .size protected_data_1a_p, .-protected_data_1a_p
+ .p2align 4
+ .protected protected_data_1b
+ .globl protected_data_1b_p
+ .type protected_data_1b_p, @function
+protected_data_1b_p:
+.LFB1:
+ .cfi_startproc
+ leaq protected_data_1b(%rip), %rax
+ ret
+ .cfi_endproc
+.LFE1:
+ .size protected_data_1b_p, .-protected_data_1b_p
+ .p2align 4
+ .globl set_protected_data_1a
+ .type set_protected_data_1a, @function
+set_protected_data_1a:
+.LFB2:
+ .cfi_startproc
+ movl %edi, protected_data_1a(%rip)
+ ret
+ .cfi_endproc
+.LFE2:
+ .size set_protected_data_1a, .-set_protected_data_1a
+ .p2align 4
+ .globl set_protected_data_1b
+ .type set_protected_data_1b, @function
+set_protected_data_1b:
+.LFB3:
+ .cfi_startproc
+ movl %edi, protected_data_1b(%rip)
+ ret
+ .cfi_endproc
+.LFE3:
+ .size set_protected_data_1b, .-set_protected_data_1b
+ .p2align 4
+ .globl check_protected_data_1a
+ .type check_protected_data_1a, @function
+check_protected_data_1a:
+.LFB4:
+ .cfi_startproc
+ xorl %eax, %eax
+ cmpl %edi, protected_data_1a(%rip)
+ setne %al
+ ret
+ .cfi_endproc
+.LFE4:
+ .size check_protected_data_1a, .-check_protected_data_1a
+ .p2align 4
+ .globl check_protected_data_1b
+ .type check_protected_data_1b, @function
+check_protected_data_1b:
+.LFB5:
+ .cfi_startproc
+ xorl %eax, %eax
+ cmpl %edi, protected_data_1b(%rip)
+ setne %al
+ ret
+ .cfi_endproc
+.LFE5:
+ .size check_protected_data_1b, .-check_protected_data_1b
+ .globl protected_data_1b
+ .data
+ .align 4
+ .type protected_data_1b, @object
+ .size protected_data_1b, 4
+protected_data_1b:
+ .long 2
+ .globl protected_data_1a
+ .align 4
+ .type protected_data_1a, @object
+ .size protected_data_1a, 4
+protected_data_1a:
+ .long 1
+ .section .note.GNU-stack,"",@progbits
+#ifdef USE_GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS
+# ifdef __LP64__
+# define ALIGN 3
+# else
+# define ALIGN 2
+# endif
+ .section ".note.gnu.property", "a"
+ .p2align ALIGN
+ .long 1f - 0f /* name length */
+ .long 5f - 2f /* data length */
+ .long 5 /* note type */
+0: .asciz "GNU" /* vendor name */
+1:
+ .p2align ALIGN
+2: .long 0xb0008000 /* pr_type. */
+ .long 4f - 3f /* pr_datasz. */
+3:
+ .long 0x1
+4:
+ .p2align ALIGN
+5:
+#endif
diff --git a/ld/testsuite/ld-x86-64/protected-data-2b.S b/ld/testsuite/ld-x86-64/protected-data-2b.S
new file mode 100644
index 0000000..da89561
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/protected-data-2b.S
@@ -0,0 +1,119 @@
+ .section .rodata.str1.8,"aMS",@progbits,1
+ .align 8
+.LC0:
+ .string "'protected_data_1a' in main and shared library doesn't have same address"
+ .align 8
+.LC1:
+ .string "'protected_data_1a' in main and shared library doesn't have same value"
+ .align 8
+.LC2:
+ .string "'protected_data_1b' in main and shared library has same address"
+ .section .rodata.str1.1,"aMS",@progbits,1
+.LC3:
+ .string "PASS"
+ .section .text.startup,"ax",@progbits
+ .p2align 4,,15
+ .globl main
+ .type main, @function
+main:
+.LFB11:
+ .cfi_startproc
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset 6, -16
+ xorl %eax, %eax
+ pushq %rbx
+ .cfi_def_cfa_offset 24
+ .cfi_offset 3, -24
+ xorl %ebx, %ebx
+ subq $8, %rsp
+ .cfi_def_cfa_offset 32
+ call protected_data_1a_p
+ movq protected_data_1a@GOTPCREL(%rip), %rbp
+ cmpq %rbp, %rax
+ je .L2
+ leaq .LC0(%rip), %rdi
+ movb $1, %bl
+ call puts
+.L2:
+ movl $-1, %edi
+ movl $-1, 0(%rbp)
+ call check_protected_data_1a
+ testl %eax, %eax
+ jne .L17
+.L3:
+ movl $-3, %edi
+ call set_protected_data_1a
+ cmpl $-3, 0(%rbp)
+ je .L4
+ leaq .LC1(%rip), %rdi
+ movl $1, %ebx
+ call puts
+.L4:
+ xorl %eax, %eax
+ call protected_data_1b_p
+ leaq protected_data_1b(%rip), %rdx
+ cmpq %rdx, %rax
+ je .L18
+.L5:
+ movl $2, %edi
+ movl $-10, protected_data_1b(%rip)
+ call check_protected_data_1b
+ testl %eax, %eax
+ jne .L19
+ movl $-30, %edi
+ call set_protected_data_1b
+ cmpl $-10, protected_data_1b(%rip)
+ je .L9
+.L7:
+ leaq .LC2(%rip), %rdi
+ movl $1, %ebx
+ call puts
+.L8:
+ addq $8, %rsp
+ .cfi_remember_state
+ .cfi_def_cfa_offset 24
+ movl %ebx, %eax
+ popq %rbx
+ .cfi_def_cfa_offset 16
+ popq %rbp
+ .cfi_def_cfa_offset 8
+ ret
+.L9:
+ .cfi_restore_state
+ testl %ebx, %ebx
+ jne .L11
+ leaq .LC3(%rip), %rdi
+ call puts
+ jmp .L8
+.L19:
+ leaq .LC2(%rip), %rdi
+ call puts
+ movl $-30, %edi
+ call set_protected_data_1b
+ cmpl $-10, protected_data_1b(%rip)
+ jne .L7
+.L11:
+ movl $1, %ebx
+ jmp .L8
+.L17:
+ leaq .LC1(%rip), %rdi
+ movl $1, %ebx
+ call puts
+ jmp .L3
+.L18:
+ leaq .LC2(%rip), %rdi
+ movl $1, %ebx
+ call puts
+ jmp .L5
+ .cfi_endproc
+.LFE11:
+ .size main, .-main
+ .globl protected_data_1b
+ .data
+ .align 4
+ .type protected_data_1b, @object
+ .size protected_data_1b, 4
+protected_data_1b:
+ .long 3
+ .section .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-x86-64/protected-func-2a.S b/ld/testsuite/ld-x86-64/protected-func-2a.S
new file mode 100644
index 0000000..35c9cd1
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/protected-func-2a.S
@@ -0,0 +1,68 @@
+ .text
+ .p2align 4
+ .protected protected_func_1a
+ .globl protected_func_1a
+ .type protected_func_1a, @function
+protected_func_1a:
+.LFB0:
+ .cfi_startproc
+ movl $1, %eax
+ ret
+ .cfi_endproc
+.LFE0:
+ .size protected_func_1a, .-protected_func_1a
+ .p2align 4
+ .protected protected_func_1b
+ .globl protected_func_1b
+ .type protected_func_1b, @function
+protected_func_1b:
+.LFB1:
+ .cfi_startproc
+ movl $2, %eax
+ ret
+ .cfi_endproc
+.LFE1:
+ .size protected_func_1b, .-protected_func_1b
+ .p2align 4
+ .globl protected_func_1a_p
+ .type protected_func_1a_p, @function
+protected_func_1a_p:
+.LFB2:
+ .cfi_startproc
+ leaq protected_func_1a(%rip), %rax
+ ret
+ .cfi_endproc
+.LFE2:
+ .size protected_func_1a_p, .-protected_func_1a_p
+ .p2align 4
+ .globl protected_func_1b_p
+ .type protected_func_1b_p, @function
+protected_func_1b_p:
+.LFB3:
+ .cfi_startproc
+ leaq protected_func_1b(%rip), %rax
+ ret
+ .cfi_endproc
+.LFE3:
+ .size protected_func_1b_p, .-protected_func_1b_p
+ .section .note.GNU-stack,"",@progbits
+#ifdef __LP64__
+# define ALIGN 3
+#else
+# define ALIGN 2
+#endif
+ .section ".note.gnu.property", "a"
+ .p2align ALIGN
+ .long 1f - 0f /* name length */
+ .long 5f - 2f /* data length */
+ .long 5 /* note type */
+0: .asciz "GNU" /* vendor name */
+1:
+ .p2align ALIGN
+2: .long 0xb0008000 /* pr_type. */
+ .long 4f - 3f /* pr_datasz. */
+3:
+ .long 0x1
+4:
+ .p2align ALIGN
+5:
diff --git a/ld/testsuite/ld-x86-64/protected-func-2b.S b/ld/testsuite/ld-x86-64/protected-func-2b.S
new file mode 100644
index 0000000..8fa4cbf
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/protected-func-2b.S
@@ -0,0 +1,83 @@
+ .text
+ .p2align 4
+ .globl protected_func_1b
+ .type protected_func_1b, @function
+protected_func_1b:
+.LFB11:
+ .cfi_startproc
+ movl $3, %eax
+ ret
+ .cfi_endproc
+.LFE11:
+ .size protected_func_1b, .-protected_func_1b
+ .section .rodata.str1.8,"aMS",@progbits,1
+ .align 8
+.LC0:
+ .string "'protected_func_1a' in main and shared library doesn't have same address"
+ .align 8
+.LC1:
+ .string "'protected_func_1a' doesn't return the correct value"
+ .align 8
+.LC2:
+ .string "'protected_func_1b' in main and shared library has same address"
+ .section .rodata.str1.1,"aMS",@progbits,1
+.LC3:
+ .string "PASS"
+ .section .text.startup,"ax",@progbits
+ .p2align 4
+ .globl main
+ .type main, @function
+main:
+.LFB12:
+ .cfi_startproc
+ pushq %r12
+ .cfi_def_cfa_offset 16
+ .cfi_offset 12, -16
+ xorl %r12d, %r12d
+ call protected_func_1a_p
+ cmpq protected_func_1a@GOTPCREL(%rip), %rax
+ je .L4
+ leaq .LC0(%rip), %rdi
+ movl $1, %r12d
+ call puts
+.L4:
+ call protected_func_1a
+ cmpl $1, %eax
+ jne .L13
+ call protected_func_1b_p
+ leaq protected_func_1b(%rip), %rdx
+ cmpq %rax, %rdx
+ je .L6
+ testl %r12d, %r12d
+ jne .L12
+ leaq .LC3(%rip), %rdi
+ call puts
+ movl %r12d, %eax
+ popq %r12
+ .cfi_remember_state
+ .cfi_def_cfa_offset 8
+ ret
+.L13:
+ .cfi_restore_state
+ leaq .LC1(%rip), %rdi
+ call puts
+ call protected_func_1b_p
+ leaq protected_func_1b(%rip), %rdx
+ cmpq %rax, %rdx
+ je .L6
+.L12:
+ movl $1, %r12d
+ movl %r12d, %eax
+ popq %r12
+ .cfi_remember_state
+ .cfi_def_cfa_offset 8
+ ret
+.L6:
+ .cfi_restore_state
+ leaq .LC2(%rip), %rdi
+ call puts
+ jmp .L12
+ .cfi_endproc
+.LFE12:
+ .size main, .-main
+ .section .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-x86-64/protected-func-2c.c b/ld/testsuite/ld-x86-64/protected-func-2c.c
new file mode 100644
index 0000000..c5ec1ec
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/protected-func-2c.c
@@ -0,0 +1,29 @@
+#include "protected-func-1.h"
+
+protected_func_type protected_func_1a_ptr = protected_func_1a;
+
+__attribute__ ((visibility("protected")))
+int
+protected_func_1a (void)
+{
+ return 1;
+}
+
+__attribute__ ((visibility("protected")))
+int
+protected_func_1b (void)
+{
+ return 2;
+}
+
+protected_func_type
+protected_func_1a_p (void)
+{
+ return protected_func_1a;
+}
+
+protected_func_type
+protected_func_1b_p (void)
+{
+ return protected_func_1b;
+}
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 3bf6250..a80f22c 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -1334,6 +1334,63 @@ if { [isnative] && [check_compiler_available] } {
{} \
"libprotected-func-1.so" \
] \
+ [list \
+ "Build libprotected-func-2a.so" \
+ "-shared" \
+ "-fPIC -Wa,-mx86-used-note=yes" \
+ { protected-func-2a.S } \
+ {{readelf -n indirect-extern-access.rd}} \
+ "libprotected-func-2a.so" \
+ ] \
+ [list \
+ "Build libprotected-func-2b.so" \
+ "-shared -z indirect-extern-access" \
+ "-fPIC -Wa,-mx86-used-note=yes" \
+ { protected-func-2c.c } \
+ {{readelf -n indirect-extern-access.rd}} \
+ "libprotected-func-2b.so" \
+ ] \
+ [list \
+ "Build libprotected-data-1a.so" \
+ "-shared -z noindirect-extern-access" \
+ "-fPIC -Wa,-mx86-used-note=yes" \
+ { protected-data-1a.c } \
+ {} \
+ "libprotected-data-1a.so" \
+ ] \
+ [list \
+ "Build libprotected-data-1b.so" \
+ "-shared -z indirect-extern-access" \
+ "-fPIC -Wa,-mx86-used-note=yes" \
+ { protected-data-1a.c } \
+ {} \
+ "libprotected-data-1b.so" \
+ ] \
+ [list \
+ "Build protected-data-1 without PIE" \
+ "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1b.so" \
+ "$NOPIE_CFLAGS -Wa,-mx86-used-note=yes" \
+ { protected-data-1b.c } \
+ {} \
+ "protected-data-1" \
+ ] \
+ [list \
+ "Build libprotected-data-2a.so" \
+ "-shared" \
+ "-fPIC -Wa,-mx86-used-note=yes \
+ -DUSE_GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS" \
+ { protected-data-2a.S } \
+ {{readelf -n indirect-extern-access.rd}} \
+ "libprotected-data-2a.so" \
+ ] \
+ [list \
+ "Build libprotected-data-2b.so" \
+ "-shared -z indirect-extern-access" \
+ "-fPIC -Wa,-mx86-used-note=yes" \
+ { protected-data-2a.S } \
+ {{readelf -n indirect-extern-access.rd}} \
+ "libprotected-data-2b.so" \
+ ] \
]
if {[istarget "x86_64-*-linux*-gnux32"]} {
@@ -1761,6 +1818,96 @@ if { [isnative] && [check_compiler_available] } {
"pass.out" \
"-fPIE" \
] \
+ [list \
+ "Run protected-func-2a without PIE" \
+ "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-2a.so" \
+ "-Wa,-mx86-used-note=yes" \
+ { protected-func-2b.S } \
+ "protected-func-2a" \
+ "pass.out" \
+ "$NOPIE_CFLAGS" \
+ ] \
+ [list \
+ "Run protected-func-2b with PIE" \
+ "-Wl,--no-as-needed -pie tmpdir/libprotected-func-2a.so" \
+ "-Wa,-mx86-used-note=yes" \
+ { protected-func-2b.S } \
+ "protected-func-2b" \
+ "pass.out" \
+ "-fPIE" \
+ ] \
+ [list \
+ "Run protected-func-2c without PIE" \
+ "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-2b.so" \
+ "-Wa,-mx86-used-note=yes" \
+ { protected-func-2b.S } \
+ "protected-func-2c" \
+ "pass.out" \
+ "$NOPIE_CFLAGS" \
+ ] \
+ [list \
+ "Run protected-func-2d with PIE" \
+ "-Wl,--no-as-needed -pie tmpdir/libprotected-func-2b.so" \
+ "-Wa,-mx86-used-note=yes" \
+ { protected-func-2b.S } \
+ "protected-func-2d" \
+ "pass.out" \
+ "-fPIE" \
+ ] \
+ [list \
+ "Run protected-data-1a without PIE" \
+ "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1a.so" \
+ "-Wa,-mx86-used-note=yes" \
+ { protected-data-1b.c } \
+ "protected-data-1a" \
+ "pass.out" \
+ "$NOPIE_CFLAGS" \
+ ] \
+ [list \
+ "Run protected-data-1b with PIE" \
+ "-Wl,--no-as-needed -pie tmpdir/libprotected-data-1a.so" \
+ "-Wa,-mx86-used-note=yes" \
+ { protected-data-1b.c } \
+ "protected-data-1b" \
+ "pass.out" \
+ "-fPIE" \
+ ] \
+ [list \
+ "Run protected-data-2a without PIE" \
+ "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2a.so" \
+ "-Wa,-mx86-used-note=yes" \
+ { protected-data-2b.S } \
+ "protected-data-2a" \
+ "pass.out" \
+ "$NOPIE_CFLAGS" \
+ ] \
+ [list \
+ "Run protected-data-2b with PIE" \
+ "-Wl,--no-as-needed -pie tmpdir/libprotected-data-2a.so" \
+ "-Wa,-mx86-used-note=yes" \
+ { protected-data-2b.S } \
+ "protected-data-2b" \
+ "pass.out" \
+ "-fPIE" \
+ ] \
+ [list \
+ "Run protected-data-2c without PIE" \
+ "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2b.so" \
+ "-Wa,-mx86-used-note=yes" \
+ { protected-data-2b.S } \
+ "protected-data-2c" \
+ "pass.out" \
+ "$NOPIE_CFLAGS" \
+ ] \
+ [list \
+ "Run protected-data-2d with PIE" \
+ "-Wl,--no-as-needed -pie tmpdir/libprotected-data-2b.so" \
+ "-Wa,-mx86-used-note=yes" \
+ { protected-data-2b.S } \
+ "protected-data-2d" \
+ "pass.out" \
+ "-fPIE" \
+ ] \
]
# Run-time tests which require working ifunc attribute support.