aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2018-01-17 14:19:08 +1030
committerAlan Modra <amodra@gmail.com>2018-01-17 18:52:57 +1030
commit1be5d8d3bbec4c9a112114993ac5c85b2b26c4c4 (patch)
treedf7f34ee05bf516ced0b7547c40ea3185087b662 /ld
parent9e390558cef76767a98123994c422d0642d86cf8 (diff)
downloadgdb-1be5d8d3bbec4c9a112114993ac5c85b2b26c4c4.zip
gdb-1be5d8d3bbec4c9a112114993ac5c85b2b26c4c4.tar.gz
gdb-1be5d8d3bbec4c9a112114993ac5c85b2b26c4c4.tar.bz2
PowerPC PLT speculative execution barriers
Spectre variant 2 mitigation for PowerPC and PowerPC64. bfd/ * elf32-ppc.c (GLINK_ENTRY_SIZE): Handle speculation barrier. (CRSETEQ, BEQCTRM): Define. (is_nonpic_glink_stub): Don't check bctr. (ppc_elf_link_hash_table_create): Init new ppc_elf_params field. (ppc_elf_relax_section): Size speculation barrier. (output_bctr): New function. (write_glink_stub): Use output_bctr. (ppc_elf_relocate_section): Use output_bctr for long branch stub. (ppc_elf_finish_dynamic_symbol): Likewise. (ppc_elf_finish_dynamic_sections): Use output_bctr. * elf32-ppc.h (struct ppc_elf_params): Add speculate_indirect_jumps. * elf64-ppc.c (CRSETEQ, BEQCTRM, BEQCTRLM): Define. (GLINK_PLTRESOLVE_SIZE): Size speculation barrier. (size_global_entry_stubs): Handle speculation barrier sizing. (plt_stub_size): Likewise. (output_bctr): New function. (build_plt_stub, build_tls_get_addr_stub): Output speculation barrier. (ppc_build_one_stub): Likewise for ppc_stub_plt_branch. (ppc_size_one_stub): Size speculation barrier in ppc_stub_plt_branch. (build_global_entry_stubs): Output speculation barrier. (ppc64_elf_build_stubs): Likewise in __glink_PLTresolve stub. * elf64-ppc.h (struct ppc64_elf_params): Add speculate_indirect_jumps. gold/ * options.h (speculate_indirect_jumps): New option. * powerpc.cc (beqctrm, beqctrlm, crseteq): New insn constants. (output_bctr): New function. (Stub_table::plt_call_size): Add space for speculation barrier. (Stub_table::branch_stub_size): Likewise. (Output_data_glink::pltresolve_size): Likewise. (Stub_table::do_write): Output speculation barriers. ld/ * emultempl/ppc32elf.em (params): Init new field. (OPTION_SPECULATE_INDIRECT_JUMPS): Define. (OPTION_NO_SPECULATE_INDIRECT_JUMPS): Define. (PARSE_AND_LIST_LONGOPTS): Handle new options. (PARSE_AND_LIST_ARGS_CASES): Likewise. (PARSE_AND_LIST_OPTIONS): Likewise. * emultempl/ppc64elf.em (params): Init new field. (OPTION_SPECULATE_INDIRECT_JUMPS): Define. (OPTION_NO_SPECULATE_INDIRECT_JUMPS): Define. (PARSE_AND_LIST_LONGOPTS): Handle --speculate-indirect-jumps. (PARSE_AND_LIST_OPTIONS): Likewise. (PARSE_AND_LIST_ARGS_CASES): Likewise. * ld.texinfo (--no-plt-thread-safe): Correct itemx. (--speculate-indirect-jumps): Document. * testsuite/ld-powerpc/elfv2exe.d, * testsuite/ld-powerpc/elfv2so.d, * testsuite/ld-powerpc/relbrlt.d, * testsuite/ld-powerpc/powerpc.exp: Disable plt alignment and speculation barriers on various tests.
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog22
-rw-r--r--ld/emultempl/ppc32elf.em20
-rw-r--r--ld/emultempl/ppc64elf.em22
-rw-r--r--ld/ld.texinfo11
-rw-r--r--ld/testsuite/ld-powerpc/elfv2exe.d2
-rw-r--r--ld/testsuite/ld-powerpc/elfv2so.d2
-rw-r--r--ld/testsuite/ld-powerpc/powerpc.exp20
-rw-r--r--ld/testsuite/ld-powerpc/relbrlt.d2
8 files changed, 84 insertions, 17 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index f95032d..9ee555b 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,6 +1,28 @@
2018-01-17 Alan Modra <amodra@gmail.com>
* emultempl/ppc32elf.em (params): Init new field.
+ (OPTION_SPECULATE_INDIRECT_JUMPS): Define.
+ (OPTION_NO_SPECULATE_INDIRECT_JUMPS): Define.
+ (PARSE_AND_LIST_LONGOPTS): Handle new options.
+ (PARSE_AND_LIST_ARGS_CASES): Likewise.
+ (PARSE_AND_LIST_OPTIONS): Likewise.
+ * emultempl/ppc64elf.em (params): Init new field.
+ (OPTION_SPECULATE_INDIRECT_JUMPS): Define.
+ (OPTION_NO_SPECULATE_INDIRECT_JUMPS): Define.
+ (PARSE_AND_LIST_LONGOPTS): Handle --speculate-indirect-jumps.
+ (PARSE_AND_LIST_OPTIONS): Likewise.
+ (PARSE_AND_LIST_ARGS_CASES): Likewise.
+ * ld.texinfo (--no-plt-thread-safe): Correct itemx.
+ (--speculate-indirect-jumps): Document.
+ * testsuite/ld-powerpc/elfv2exe.d,
+ * testsuite/ld-powerpc/elfv2so.d,
+ * testsuite/ld-powerpc/relbrlt.d,
+ * testsuite/ld-powerpc/powerpc.exp: Disable plt alignment and
+ speculation barriers on various tests.
+
+2018-01-17 Alan Modra <amodra@gmail.com>
+
+ * emultempl/ppc32elf.em (params): Init new field.
(enum ppc32_opt): New enum to define OPTION_* values. Add
OPTION_PLT_ALIGN and OPTION_NO_PLT_ALIGN.
(PARSE_AND_LIST_LONGOPTS): Handle new options.
diff --git a/ld/emultempl/ppc32elf.em b/ld/emultempl/ppc32elf.em
index 70dd5a0..4e71a78 100644
--- a/ld/emultempl/ppc32elf.em
+++ b/ld/emultempl/ppc32elf.em
@@ -38,7 +38,7 @@ static int notlsopt = 0;
/* Choose the correct place for .got. */
static int old_got = 0;
-static struct ppc_elf_params params = { PLT_UNSET, 0, -1,
+static struct ppc_elf_params params = { PLT_UNSET, 0, 1, -1,
0, 0, 0, 0, 0, 0, 0 };
static void
@@ -246,6 +246,8 @@ enum ppc32_opt
OPTION_NO_TLS_GET_ADDR_OPT,
OPTION_NEW_PLT,
OPTION_OLD_PLT,
+ OPTION_SPECULATE_INDIRECT_JUMPS,
+ OPTION_NO_SPECULATE_INDIRECT_JUMPS,
OPTION_PLT_ALIGN,
OPTION_NO_PLT_ALIGN,
OPTION_OLD_GOT,
@@ -267,6 +269,8 @@ if test -z "$VXWORKS_BASE_EM_FILE" ; then
PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
{ "secure-plt", no_argument, NULL, OPTION_NEW_PLT },
{ "bss-plt", no_argument, NULL, OPTION_OLD_PLT },
+ { "speculate-indirect-jumps", no_argument, NULL, OPTION_SPECULATE_INDIRECT_JUMPS },
+ { "no-speculate-indirect-jumps", no_argument, NULL, OPTION_NO_SPECULATE_INDIRECT_JUMPS },
{ "plt-align", no_argument, NULL, OPTION_PLT_ALIGN },
{ "no-plt-align", no_argument, NULL, OPTION_NO_PLT_ALIGN },
{ "sdata-got", no_argument, NULL, OPTION_OLD_GOT },'
@@ -300,6 +304,12 @@ if test -z "$VXWORKS_BASE_EM_FILE" ; then
--bss-plt Force old-style BSS PLT.\n"
));
fprintf (file, _("\
+ --speculate-indirect-jumps PLT call stubs without speculation barrier.\n"
+ ));
+ fprintf (file, _("\
+ --no-speculate-indirect-jumps PLT call stubs with speculation barrier.\n"
+ ));
+ fprintf (file, _("\
--plt-align Align PLT call stubs to fit cache lines.\n"
));
fprintf (file, _("\
@@ -350,6 +360,14 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
params.plt_style = PLT_OLD;
break;
+ case OPTION_SPECULATE_INDIRECT_JUMPS:
+ params.speculate_indirect_jumps = 1;
+ break;
+
+ case OPTION_NO_SPECULATE_INDIRECT_JUMPS:
+ params.speculate_indirect_jumps = 0;
+ break;
+
case OPTION_PLT_ALIGN:
params.plt_stub_align = 5;
break;
diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em
index 840bd44..c7c27b0 100644
--- a/ld/emultempl/ppc64elf.em
+++ b/ld/emultempl/ppc64elf.em
@@ -38,7 +38,7 @@ static struct ppc64_elf_params params = { NULL,
&ppc_layout_sections_again,
1, -1, 0,
${DEFAULT_PLT_STATIC_CHAIN-0}, -1, 5,
- -1, 0, -1, -1, 0};
+ -1, 1, 0, -1, -1, 0};
/* Fake input file for stubs. */
static lang_input_statement_type *stub_file;
@@ -692,6 +692,8 @@ enum ppc64_opt
OPTION_NO_PLT_STATIC_CHAIN,
OPTION_PLT_THREAD_SAFE,
OPTION_NO_PLT_THREAD_SAFE,
+ OPTION_SPECULATE_INDIRECT_JUMPS,
+ OPTION_NO_SPECULATE_INDIRECT_JUMPS,
OPTION_PLT_ALIGN,
OPTION_NO_PLT_ALIGN,
OPTION_PLT_LOCALENTRY,
@@ -719,6 +721,8 @@ PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
{ "no-plt-static-chain", no_argument, NULL, OPTION_NO_PLT_STATIC_CHAIN },
{ "plt-thread-safe", no_argument, NULL, OPTION_PLT_THREAD_SAFE },
{ "no-plt-thread-safe", no_argument, NULL, OPTION_NO_PLT_THREAD_SAFE },
+ { "speculate-indirect-jumps", no_argument, NULL, OPTION_SPECULATE_INDIRECT_JUMPS },
+ { "no-speculate-indirect-jumps", no_argument, NULL, OPTION_NO_SPECULATE_INDIRECT_JUMPS },
{ "plt-align", optional_argument, NULL, OPTION_PLT_ALIGN },
{ "no-plt-align", no_argument, NULL, OPTION_NO_PLT_ALIGN },
{ "plt-localentry", optional_argument, NULL, OPTION_PLT_LOCALENTRY },
@@ -760,7 +764,13 @@ PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
--plt-thread-safe PLT call stubs with load-load barrier.\n"
));
fprintf (file, _("\
- --no-plt-thread-safe PLT call stubs without barrier.\n"
+ --no-plt-thread-safe PLT call stubs without load-load barrier.\n"
+ ));
+ fprintf (file, _("\
+ --speculate-indirect-jumps PLT call stubs without speculation barrier.\n"
+ ));
+ fprintf (file, _("\
+ --no-speculate-indirect-jumps PLT call stubs with speculation barrier.\n"
));
fprintf (file, _("\
--plt-align [=<align>] Align PLT call stubs to fit cache lines.\n"
@@ -850,6 +860,14 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
params.plt_thread_safe = 0;
break;
+ case OPTION_SPECULATE_INDIRECT_JUMPS:
+ params.speculate_indirect_jumps = 1;
+ break;
+
+ case OPTION_NO_SPECULATE_INDIRECT_JUMPS:
+ params.speculate_indirect_jumps = 0;
+ break;
+
case OPTION_PLT_ALIGN:
if (optarg != NULL)
{
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 94d340c..c89915f 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -7635,7 +7635,7 @@ chain since there is never any need to do so on a PLT call.
@kindex --plt-thread-safe
@kindex --no-plt-thread-safe
@item --plt-thread-safe
-@itemx --no-thread-safe
+@itemx --no-plt-thread-safe
With power7's weakly ordered memory model, it is possible when using
lazy binding for ld.so to update a plt entry in one thread and have
another thread see the individual plt entry words update in the wrong
@@ -7646,6 +7646,15 @@ looks for calls to commonly used functions that create threads, and if
seen, adds the necessary barriers. Use these options to change the
default behaviour.
+@cindex PowerPC64 PLT call stub speculative execution barrier
+@kindex --speculate-indirect-jumps
+@kindex --no-speculate-indirect-jumps
+@item --speculate-indirect-jumps
+@itemx --no-speculate-indirect-jumps
+Use these options to control whether all indirect branch instructions
+emitted by @code{ld}, such as those in the PLT, have a speculative
+execution barrier to mitigate Spectre variant 2 attacks.
+
@cindex PowerPC64 ELFv2 PLT localentry optimization
@kindex --plt-localentry
@kindex --no-plt-localentry
diff --git a/ld/testsuite/ld-powerpc/elfv2exe.d b/ld/testsuite/ld-powerpc/elfv2exe.d
index 77bf6e2..fa5b622 100644
--- a/ld/testsuite/ld-powerpc/elfv2exe.d
+++ b/ld/testsuite/ld-powerpc/elfv2exe.d
@@ -1,6 +1,6 @@
#source: elfv2.s
#as: -a64
-#ld: -melf64ppc --defsym f2=0x1234 --defsym f3=0x10008888 --defsym f4=0x1200000 --defsym _start=f1
+#ld: -melf64ppc --speculate-indirect-jumps --defsym f2=0x1234 --defsym f3=0x10008888 --defsym f4=0x1200000 --defsym _start=f1
#objdump: -dr
.*
diff --git a/ld/testsuite/ld-powerpc/elfv2so.d b/ld/testsuite/ld-powerpc/elfv2so.d
index e7cd45c..1c048e1 100644
--- a/ld/testsuite/ld-powerpc/elfv2so.d
+++ b/ld/testsuite/ld-powerpc/elfv2so.d
@@ -1,6 +1,6 @@
#source: elfv2.s
#as: -a64
-#ld: -melf64ppc -shared
+#ld: -melf64ppc -shared --speculate-indirect-jumps
#objdump: -dr
.*
diff --git a/ld/testsuite/ld-powerpc/powerpc.exp b/ld/testsuite/ld-powerpc/powerpc.exp
index 217b443..d604787 100644
--- a/ld/testsuite/ld-powerpc/powerpc.exp
+++ b/ld/testsuite/ld-powerpc/powerpc.exp
@@ -121,11 +121,11 @@ set ppcelftests {
"tls32"}
{"TLS32 helper shared library" "-shared -melf32ppc tmpdir/tlslib32.o" "" "" {}
{} "libtlslib32.so"}
- {"TLS32 dynamic exec" "-melf32ppc --no-ld-generated-unwind-info --hash-style=sysv tmpdir/tls32.o tmpdir/libtlslib32.so" "" "" {}
+ {"TLS32 dynamic exec" "-melf32ppc --no-plt-align --speculate-indirect-jumps --no-ld-generated-unwind-info --hash-style=sysv tmpdir/tls32.o tmpdir/libtlslib32.so" "" "" {}
{{readelf -WSsrl tlsexe32.r} {objdump -dr tlsexe32.d}
{objdump -sj.got tlsexe32.g} {objdump -sj.tdata tlsexe32.t}}
"tlsexe32"}
- {"TLS32 shared" "-shared -melf32ppc --no-ld-generated-unwind-info --hash-style=sysv tmpdir/tls32.o" "" "" {}
+ {"TLS32 shared" "-shared -melf32ppc --no-plt-align --speculate-indirect-jumps --no-ld-generated-unwind-info --hash-style=sysv tmpdir/tls32.o" "" "" {}
{{readelf -WSsrl tlsso32.r} {objdump -dr tlsso32.d}
{objdump -sj.got tlsso32.g} {objdump -sj.tdata tlsso32.t}}
"tls32.so"}
@@ -147,7 +147,7 @@ set ppcelftests {
{"TLS32 DLL" "-shared -melf32ppc --version-script tlsdll.ver" ""
"-a32" {tlsdll_32.s}
{} "tlsdll32.so"}
- {"TLS32 opt 5" "-melf32ppc -shared --gc-sections --secure-plt tmpdir/tlsdll32.so" "" "-a32" {tlsopt5_32.s}
+ {"TLS32 opt 5" "-melf32ppc -shared --gc-sections --secure-plt --no-plt-align --speculate-indirect-jumps tmpdir/tlsdll32.so" "" "-a32" {tlsopt5_32.s}
{{objdump -dr tlsopt5_32.d}}
"tlsopt5_32"}
{"Shared library with global symbol" "-shared -melf32ppc" "" "-a32" {sdalib.s}
@@ -174,15 +174,15 @@ set ppc64elftests {
{} "libtlslib.so"}
{"TLS helper old shared lib" "-shared -melf64ppc" "" "-a64" {oldtlslib.s}
{} "liboldlib.so"}
- {"TLS dynamic exec" "-melf64ppc --no-plt-align --no-ld-generated-unwind-info --hash-style=sysv tmpdir/tls.o tmpdir/libtlslib.so" "" "" {}
+ {"TLS dynamic exec" "-melf64ppc --no-plt-align --speculate-indirect-jumps --no-ld-generated-unwind-info --hash-style=sysv tmpdir/tls.o tmpdir/libtlslib.so" "" "" {}
{{readelf -WSsrl tlsexe.r} {objdump -dr tlsexe.d}
{objdump -sj.got tlsexe.g} {objdump -sj.tdata tlsexe.t}}
"tlsexe"}
- {"TLS dynamic old" "-melf64ppc --no-plt-align --no-ld-generated-unwind-info --hash-style=sysv tmpdir/tls.o tmpdir/liboldlib.so" "" "" {}
+ {"TLS dynamic old" "-melf64ppc --no-plt-align --speculate-indirect-jumps --no-ld-generated-unwind-info --hash-style=sysv tmpdir/tls.o tmpdir/liboldlib.so" "" "" {}
{{readelf -WSsrl tlsexe.r} {objdump -dr tlsexe.d}
{objdump -sj.got tlsexe.g} {objdump -sj.tdata tlsexe.t}}
"tlsexeold"}
- {"TLS shared" "-shared -melf64ppc --no-plt-align --no-ld-generated-unwind-info --hash-style=sysv tmpdir/tls.o" "" "" {}
+ {"TLS shared" "-shared -melf64ppc --no-plt-align --speculate-indirect-jumps --no-ld-generated-unwind-info --hash-style=sysv tmpdir/tls.o" "" "" {}
{{readelf -WSsrl tlsso.r} {objdump -dr tlsso.d}
{objdump -sj.got tlsso.g} {objdump -sj.tdata tlsso.t}}
"tls.so"}
@@ -190,17 +190,17 @@ set ppc64elftests {
{{objdump -dr tlstoc.d} {objdump -sj.got tlstoc.g}
{objdump -sj.tdata tlstoc.t}}
"tlstoc"}
- {"TLSTOC dynamic exec" "-melf64ppc --no-plt-align --no-ld-generated-unwind-info --hash-style=sysv tmpdir/tlstoc.o tmpdir/libtlslib.so" ""
+ {"TLSTOC dynamic exec" "-melf64ppc --no-plt-align --speculate-indirect-jumps --no-ld-generated-unwind-info --hash-style=sysv tmpdir/tlstoc.o tmpdir/libtlslib.so" ""
"" {}
{{readelf -WSsrl tlsexetoc.r} {objdump -dr tlsexetoc.d}
{objdump -sj.got tlsexetoc.g} {objdump -sj.tdata tlsexetoc.t}}
"tlsexetoc"}
- {"TLSTOC dynamic old" "-melf64ppc --no-plt-align --no-ld-generated-unwind-info --hash-style=sysv tmpdir/tlstoc.o tmpdir/liboldlib.so" ""
+ {"TLSTOC dynamic old" "-melf64ppc --no-plt-align --speculate-indirect-jumps --no-ld-generated-unwind-info --hash-style=sysv tmpdir/tlstoc.o tmpdir/liboldlib.so" ""
"" {}
{{readelf -WSsrl tlsexetoc.r} {objdump -dr tlsexetoc.d}
{objdump -sj.got tlsexetoc.g} {objdump -sj.tdata tlsexetoc.t}}
"tlsexetocold"}
- {"TLSTOC shared" "-shared -melf64ppc --no-plt-align --no-ld-generated-unwind-info --hash-style=sysv tmpdir/tlstoc.o" "" "" {}
+ {"TLSTOC shared" "-shared -melf64ppc --no-plt-align --speculate-indirect-jumps --no-ld-generated-unwind-info --hash-style=sysv tmpdir/tlstoc.o" "" "" {}
{{readelf -WSsrl tlstocso.r} {objdump -dr tlstocso.d}
{objdump -sj.got tlstocso.g} {objdump -sj.tdata tlstocso.t}}
"tlstoc.so"}
@@ -221,7 +221,7 @@ set ppc64elftests {
"tlsopt4"}
{"TLS DLL" "-shared -melf64ppc --version-script tlsdll.ver" "" "-a64" {tlsdll.s}
{} "tlsdll.so"}
- {"TLS opt 5" "-melf64ppc --no-plt-align -shared --gc-sections --no-plt-localentry tmpdir/tlsdll.so" "" "-a64" {tlsopt5.s}
+ {"TLS opt 5" "-melf64ppc --no-plt-align --speculate-indirect-jumps -shared --gc-sections --no-plt-localentry tmpdir/tlsdll.so" "" "-a64" {tlsopt5.s}
{{objdump -dr tlsopt5.d} {readelf -wf tlsopt5.wf}}
"tlsopt5"}
{"sym@tocbase" "-shared -melf64ppc" "" "-a64" {symtocbase-1.s symtocbase-2.s}
diff --git a/ld/testsuite/ld-powerpc/relbrlt.d b/ld/testsuite/ld-powerpc/relbrlt.d
index 6f3db7d..510ba84 100644
--- a/ld/testsuite/ld-powerpc/relbrlt.d
+++ b/ld/testsuite/ld-powerpc/relbrlt.d
@@ -1,6 +1,6 @@
#source: relbrlt.s
#as: -a64
-#ld: -melf64ppc --no-plt-align --no-ld-generated-unwind-info --emit-relocs
+#ld: -melf64ppc --no-plt-align --speculate-indirect-jumps --no-ld-generated-unwind-info --emit-relocs
#objdump: -Dr
.*