From: liuhongt Date: Mon, 16 Mar 2020 03:03:12 +0000 (+0800) Subject: Improve -mlfence-after-load X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a09f656b267b9a684f038fba7cadfe98e2f18892;p=binutils-gdb.git Improve -mlfence-after-load 1.Implict load for POP/POPF/POPA/XLATB, no load for Anysize insns 2. Add -mlfence-before-ret=shl/yes, adjust operand size of or/not/shl according to ret's. 3. Issue warning for REP CMPS/SCAS since they would affect control flow behavior. 4. Adjust testcases and documents. gas/Changelog: * config/tc-i386.c (lfence_before_ret_shl): New member. (load_insn_p): implict load for POP/POPA/POPF/XLATB, no load for Anysize insns. (insert_after_load): Issue warning for REP CMPS/SCAS. (insert_before_before): Handle iret, Handle -mlfence-before-ret=shl, Adjust operand size of or/not/shl to ret's, (md_parse_option): Change -mlfence-before-ret=[none|not|or] to -mlfence-before-ret=[none/not/or/shl/yes]. Enable -mlfence-before-ret=shl when -mlfence-beofre-indirect-branch=all and no explict -mlfence-before-ret option. (md_show_usage): Ditto. * doc/c-i386.texi: Ditto. * testsuite/gas/i386/i386.exp: Add new testcases. * testsuite/gas/i386/lfence-load-b.d: New. * testsuite/gas/i386/lfence-load-b.e: New. * testsuite/gas/i386/lfence-load.d: Modified. * testsuite/gas/i386/lfence-load.e: New. * testsuite/gas/i386/lfence-load.s: Modified. * testsuite/gas/i386/lfence-ret-a.d: Modified. * testsuite/gas/i386/lfence-ret-b.d: Modified. * testsuite/gas/i386/lfence-ret-c.d: New. * testsuite/gas/i386/lfence-ret-d.d: New. * testsuite/gas/i386/lfence-ret.s: Modified. * testsuite/gas/i386/x86-64-lfence-load-b.d: New. * testsuite/gas/i386/x86-64-lfence-load.d: Modified. * testsuite/gas/i386/x86-64-lfence-load.s: Modified. * testsuite/gas/i386/x86-64-lfence-ret-a.d: Modified. * testsuite/gas/i386/x86-64-lfence-ret-b.d: Modified. * testsuite/gas/i386/x86-64-lfence-ret-c.d: New. * testsuite/gas/i386/x86-64-lfence-ret-d.d: New * testsuite/gas/i386/x86-64-lfence-ret-e.d: New. * testsuite/gas/i386/x86-64-lfence-ret.e: New. * testsuite/gas/i386/x86-64-lfence-ret.s: New. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index f31504b864d..c4df0e12b66 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,39 @@ +2020-04-26 Hongtao Liu PR ld/25861 diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 093497becdb..a692c457a5c 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -647,7 +647,8 @@ static enum lfence_before_ret_kind { lfence_before_ret_none = 0, lfence_before_ret_not, - lfence_before_ret_or + lfence_before_ret_or, + lfence_before_ret_shl } lfence_before_ret; @@ -4350,22 +4351,28 @@ load_insn_p (void) if (!any_vex_p) { - /* lea */ - if (i.tm.base_opcode == 0x8d) + /* Anysize insns: lea, invlpg, clflush, prefetchnta, prefetcht0, + prefetcht1, prefetcht2, prefetchtw, bndmk, bndcl, bndcu, bndcn, + bndstx, bndldx, prefetchwt1, clflushopt, clwb, cldemote. */ + if (i.tm.opcode_modifier.anysize) return 0; - /* pop */ - if ((i.tm.base_opcode & ~7) == 0x58 - || (i.tm.base_opcode == 0x8f && i.tm.extension_opcode == 0)) + /* pop, popf, popa. */ + if (strcmp (i.tm.name, "pop") == 0 + || i.tm.base_opcode == 0x9d + || i.tm.base_opcode == 0x61) return 1; /* movs, cmps, lods, scas. */ if ((i.tm.base_opcode | 0xb) == 0xaf) return 1; - /* outs */ - if (base_opcode == 0x6f) + /* outs, xlatb. */ + if (base_opcode == 0x6f + || i.tm.base_opcode == 0xd7) return 1; + /* NB: For AMD-specific insns with implicit memory operands, + they're intentionally not covered. */ } /* No memory operand. */ @@ -4506,6 +4513,22 @@ insert_lfence_after (void) { if (lfence_after_load && load_insn_p ()) { + /* There are also two REP string instructions that require + special treatment. Specifically, the compare string (CMPS) + and scan string (SCAS) instructions set EFLAGS in a manner + that depends on the data being compared/scanned. When used + with a REP prefix, the number of iterations may therefore + vary depending on this data. If the data is a program secret + chosen by the adversary using an LVI method, + then this data-dependent behavior may leak some aspect + of the secret. */ + if (((i.tm.base_opcode | 0x1) == 0xa7 + || (i.tm.base_opcode | 0x1) == 0xaf) + && i.prefix[REP_PREFIX]) + { + as_warn (_("`%s` changes flags which would affect control flow behavior"), + i.tm.name); + } char *p = frag_more (3); *p++ = 0xf; *p++ = 0xae; @@ -4568,12 +4591,13 @@ insert_lfence_before (void) return; } - /* Output or/not and lfence before ret. */ + /* Output or/not/shl and lfence before ret/lret/iret. */ if (lfence_before_ret != lfence_before_ret_none && (i.tm.base_opcode == 0xc2 || i.tm.base_opcode == 0xc3 || i.tm.base_opcode == 0xca - || i.tm.base_opcode == 0xcb)) + || i.tm.base_opcode == 0xcb + || i.tm.base_opcode == 0xcf)) { if (last_insn.kind != last_insn_other && last_insn.seg == now_seg) @@ -4583,33 +4607,59 @@ insert_lfence_before (void) last_insn.name, i.tm.name); return; } - if (lfence_before_ret == lfence_before_ret_or) - { - /* orl: 0x830c2400. */ - p = frag_more ((flag_code == CODE_64BIT ? 1 : 0) + 4 + 3); - if (flag_code == CODE_64BIT) - *p++ = 0x48; - *p++ = 0x83; - *p++ = 0xc; - *p++ = 0x24; - *p++ = 0x0; - } - else - { - p = frag_more ((flag_code == CODE_64BIT ? 2 : 0) + 6 + 3); - /* notl: 0xf71424. */ - if (flag_code == CODE_64BIT) - *p++ = 0x48; + + /* lret or iret. */ + bfd_boolean lret = (i.tm.base_opcode | 0x5) == 0xcf; + bfd_boolean has_rexw = i.prefix[REX_PREFIX] & REX_W; + char prefix = 0x0; + /* Default operand size for far return is 32 bits, + 64 bits for near return. */ + /* Near ret ingore operand size override under CPU64. */ + if ((!lret && flag_code == CODE_64BIT) || has_rexw) + prefix = 0x48; + else if (i.prefix[DATA_PREFIX]) + prefix = 0x66; + + if (lfence_before_ret == lfence_before_ret_not) + { + /* not: 0xf71424, may add prefix + for operand size override or 64-bit code. */ + p = frag_more ((prefix ? 2 : 0) + 6 + 3); + if (prefix) + *p++ = prefix; *p++ = 0xf7; *p++ = 0x14; *p++ = 0x24; - /* notl: 0xf71424. */ - if (flag_code == CODE_64BIT) - *p++ = 0x48; + if (prefix) + *p++ = prefix; *p++ = 0xf7; *p++ = 0x14; *p++ = 0x24; } + else + { + p = frag_more ((prefix ? 1 : 0) + 4 + 3); + if (prefix) + *p++ = prefix; + if (lfence_before_ret == lfence_before_ret_or) + { + /* or: 0x830c2400, may add prefix + for operand size override or 64-bit code. */ + *p++ = 0x83; + *p++ = 0x0c; + } + else + { + /* shl: 0xc1242400, may add prefix + for operand size override or 64-bit code. */ + *p++ = 0xc1; + *p++ = 0x24; + } + + *p++ = 0x24; + *p++ = 0x0; + } + *p++ = 0xf; *p++ = 0xae; *p = 0xe8; @@ -12995,7 +13045,11 @@ md_parse_option (int c, const char *arg) case OPTION_MLFENCE_BEFORE_INDIRECT_BRANCH: if (strcasecmp (arg, "all") == 0) - lfence_before_indirect_branch = lfence_branch_all; + { + lfence_before_indirect_branch = lfence_branch_all; + if (lfence_before_ret == lfence_before_ret_none) + lfence_before_ret = lfence_before_ret_shl; + } else if (strcasecmp (arg, "memory") == 0) lfence_before_indirect_branch = lfence_branch_memory; else if (strcasecmp (arg, "register") == 0) @@ -13012,6 +13066,8 @@ md_parse_option (int c, const char *arg) lfence_before_ret = lfence_before_ret_or; else if (strcasecmp (arg, "not") == 0) lfence_before_ret = lfence_before_ret_not; + else if (strcasecmp (arg, "shl") == 0 || strcasecmp (arg, "yes") == 0) + lfence_before_ret = lfence_before_ret_shl; else if (strcasecmp (arg, "none") == 0) lfence_before_ret = lfence_before_ret_none; else @@ -13382,7 +13438,7 @@ md_show_usage (FILE *stream) -mlfence-before-indirect-branch=[none|all|register|memory] (default: none)\n\ generate lfence before indirect near branch\n")); fprintf (stream, _("\ - -mlfence-before-ret=[none|or|not] (default: none)\n\ + -mlfence-before-ret=[none|or|not|shl|yes] (default: none)\n\ generate lfence before ret\n")); fprintf (stream, _("\ -mamd64 accept only AMD64 ISA [default]\n")); diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi index 628fb1ad5a6..4acece43947 100644 --- a/gas/doc/c-i386.texi +++ b/gas/doc/c-i386.texi @@ -488,6 +488,8 @@ before indirect near branch instructions. @option{-mlfence-before-indirect-branch=@var{all}} will generate lfence before indirect near branch via register and issue a warning before indirect near branch via memory. +It also implicitly sets @option{-mlfence-before-ret=@var{shl}} when +there's no explict @option{-mlfence-before-ret=}. @option{-mlfence-before-indirect-branch=@var{register}} will generate lfence before indirect near branch via register. @option{-mlfence-before-indirect-branch=@var{memory}} will issue a @@ -501,15 +503,17 @@ after loading branch target register. @cindex @samp{-mlfence-before-ret=} option, i386 @cindex @samp{-mlfence-before-ret=} option, x86-64 @item -mlfence-before-ret=@var{none} +@item -mlfence-before-ret=@var{shl} @item -mlfence-before-ret=@var{or} +@item -mlfence-before-ret=@var{yes} @itemx -mlfence-before-ret=@var{not} These options control whether the assembler should generate lfence before ret. @option{-mlfence-before-ret=@var{or}} will generate generate or instruction with lfence. -@option{-mlfence-before-ret=@var{not}} will generate not instruction -with lfence. -@option{-mlfence-before-ret=@var{none}} will not generate lfence, -which is the default. +@option{-mlfence-before-ret=@var{shl/yes}} will generate shl instruction +with lfence. @option{-mlfence-before-ret=@var{not}} will generate not +instruction with lfence. @option{-mlfence-before-ret=@var{none}} will not +generate lfence, which is the default. @cindex @samp{-mx86-used-note=} option, i386 @cindex @samp{-mx86-used-note=} option, x86-64 diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index 9dacc119062..3bacb80178a 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -535,6 +535,8 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]] run_dump_test "lfence-indbr-c" run_dump_test "lfence-ret-a" run_dump_test "lfence-ret-b" + run_dump_test "lfence-ret-c" + run_dump_test "lfence-ret-d" run_dump_test "lfence-byte" # These tests require support for 8 and 16 bit relocs, @@ -1122,6 +1124,9 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t run_dump_test "x86-64-lfence-indbr-c" run_dump_test "x86-64-lfence-ret-a" run_dump_test "x86-64-lfence-ret-b" + run_dump_test "x86-64-lfence-ret-c" + run_dump_test "x86-64-lfence-ret-d" + run_dump_test "x86-64-lfence-ret-e" run_dump_test "x86-64-lfence-byte" if { ![istarget "*-*-aix*"] diff --git a/gas/testsuite/gas/i386/lfence-load.d b/gas/testsuite/gas/i386/lfence-load.d index cd7e7f76dfe..0d355df5561 100644 --- a/gas/testsuite/gas/i386/lfence-load.d +++ b/gas/testsuite/gas/i386/lfence-load.d @@ -1,5 +1,6 @@ #as: -mlfence-after-load=yes #objdump: -dw +#warning_output: lfence-load.e #name: -mlfence-after-load=yes .*: +file format .* @@ -15,6 +16,31 @@ Disassembly of section .text: +[a-f0-9]+: 0f c7 75 00 vmptrld 0x0\(%ebp\) +[a-f0-9]+: 0f ae e8 lfence +[a-f0-9]+: 66 0f c7 75 00 vmclear 0x0\(%ebp\) + +[a-f0-9]+: 66 0f 38 82 55 00 invpcid 0x0\(%ebp\),%edx + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 0f 01 7d 00 invlpg 0x0\(%ebp\) + +[a-f0-9]+: 0f ae 7d 00 clflush 0x0\(%ebp\) + +[a-f0-9]+: 66 0f ae 7d 00 clflushopt 0x0\(%ebp\) + +[a-f0-9]+: 66 0f ae 75 00 clwb 0x0\(%ebp\) + +[a-f0-9]+: 0f 1c 45 00 cldemote 0x0\(%ebp\) + +[a-f0-9]+: f3 0f 1b 4d 00 bndmk 0x0\(%ebp\),%bnd1 + +[a-f0-9]+: f3 0f 1a 4d 00 bndcl 0x0\(%ebp\),%bnd1 + +[a-f0-9]+: f2 0f 1a 4d 00 bndcu 0x0\(%ebp\),%bnd1 + +[a-f0-9]+: f2 0f 1b 4d 00 bndcn 0x0\(%ebp\),%bnd1 + +[a-f0-9]+: 0f 1b 4d 00 bndstx %bnd1,0x0\(%ebp\) + +[a-f0-9]+: 0f 1a 4d 00 bndldx 0x0\(%ebp\),%bnd1 + +[a-f0-9]+: 0f 18 4d 00 prefetcht0 0x0\(%ebp\) + +[a-f0-9]+: 0f 18 55 00 prefetcht1 0x0\(%ebp\) + +[a-f0-9]+: 0f 18 5d 00 prefetcht2 0x0\(%ebp\) + +[a-f0-9]+: 0f 0d 4d 00 prefetchw 0x0\(%ebp\) + +[a-f0-9]+: 1f pop %ds + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 9d popf + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 61 popa + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: d7 xlat %ds:\(%ebx\) + +[a-f0-9]+: 0f ae e8 lfence +[a-f0-9]+: d9 55 00 fsts 0x0\(%ebp\) +[a-f0-9]+: d9 45 00 flds 0x0\(%ebp\) +[a-f0-9]+: 0f ae e8 lfence diff --git a/gas/testsuite/gas/i386/lfence-load.e b/gas/testsuite/gas/i386/lfence-load.e new file mode 100644 index 00000000000..1ee49da7fd1 --- /dev/null +++ b/gas/testsuite/gas/i386/lfence-load.e @@ -0,0 +1,3 @@ +.*: Assembler messages: +.*:??: Warning: `scas` changes flags which would affect control flow behavior +.*:??: Warning: `cmps` changes flags which would affect control flow behavior diff --git a/gas/testsuite/gas/i386/lfence-load.s b/gas/testsuite/gas/i386/lfence-load.s index b417ac644e9..4b4aa1610b3 100644 --- a/gas/testsuite/gas/i386/lfence-load.s +++ b/gas/testsuite/gas/i386/lfence-load.s @@ -4,6 +4,26 @@ _start: lgdt (%ebp) vmptrld (%ebp) vmclear (%ebp) + invpcid (%ebp), %edx + invlpg (%ebp) + clflush (%ebp) + clflushopt (%ebp) + clwb (%ebp) + cldemote (%ebp) + bndmk (%ebp), %bnd1 + bndcl (%ebp), %bnd1 + bndcu (%ebp), %bnd1 + bndcn (%ebp), %bnd1 + bndstx %bnd1, (%ebp) + bndldx (%ebp), %bnd1 + prefetcht0 (%ebp) + prefetcht1 (%ebp) + prefetcht2 (%ebp) + prefetchw (%ebp) + pop %ds + popf + popa + xlatb (%ebx) fsts (%ebp) flds (%ebp) fistl (%ebp) diff --git a/gas/testsuite/gas/i386/lfence-ret-a.d b/gas/testsuite/gas/i386/lfence-ret-a.d index 719cf1b472e..aa358576647 100644 --- a/gas/testsuite/gas/i386/lfence-ret-a.d +++ b/gas/testsuite/gas/i386/lfence-ret-a.d @@ -9,10 +9,28 @@ Disassembly of section .text: 0+ <_start>: + +[a-f0-9]+: 66 83 0c 24 00 orw \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c3 retw + +[a-f0-9]+: 66 83 0c 24 00 orw \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c2 14 00 retw \$0x14 +[a-f0-9]+: 83 0c 24 00 orl \$0x0,\(%esp\) +[a-f0-9]+: 0f ae e8 lfence +[a-f0-9]+: c3 ret +[a-f0-9]+: 83 0c 24 00 orl \$0x0,\(%esp\) +[a-f0-9]+: 0f ae e8 lfence +[a-f0-9]+: c2 1e 00 ret \$0x1e + +[a-f0-9]+: 66 83 0c 24 00 orw \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 cb lretw + +[a-f0-9]+: 66 83 0c 24 00 orw \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 ca 28 00 lretw \$0x28 + +[a-f0-9]+: 83 0c 24 00 orl \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: cb lret + +[a-f0-9]+: 83 0c 24 00 orl \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: ca 28 00 lret \$0x28 #pass diff --git a/gas/testsuite/gas/i386/lfence-ret-b.d b/gas/testsuite/gas/i386/lfence-ret-b.d index e3914b9c285..77001c425ef 100644 --- a/gas/testsuite/gas/i386/lfence-ret-b.d +++ b/gas/testsuite/gas/i386/lfence-ret-b.d @@ -9,6 +9,14 @@ Disassembly of section .text: 0+ <_start>: + +[a-f0-9]+: 66 f7 14 24 notw \(%esp\) + +[a-f0-9]+: 66 f7 14 24 notw \(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c3 retw + +[a-f0-9]+: 66 f7 14 24 notw \(%esp\) + +[a-f0-9]+: 66 f7 14 24 notw \(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c2 14 00 retw \$0x14 +[a-f0-9]+: f7 14 24 notl \(%esp\) +[a-f0-9]+: f7 14 24 notl \(%esp\) +[a-f0-9]+: 0f ae e8 lfence @@ -17,4 +25,20 @@ Disassembly of section .text: +[a-f0-9]+: f7 14 24 notl \(%esp\) +[a-f0-9]+: 0f ae e8 lfence +[a-f0-9]+: c2 1e 00 ret \$0x1e + +[a-f0-9]+: 66 f7 14 24 notw \(%esp\) + +[a-f0-9]+: 66 f7 14 24 notw \(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 cb lretw + +[a-f0-9]+: 66 f7 14 24 notw \(%esp\) + +[a-f0-9]+: 66 f7 14 24 notw \(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 ca 28 00 lretw \$0x28 + +[a-f0-9]+: f7 14 24 notl \(%esp\) + +[a-f0-9]+: f7 14 24 notl \(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: cb lret + +[a-f0-9]+: f7 14 24 notl \(%esp\) + +[a-f0-9]+: f7 14 24 notl \(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: ca 28 00 lret \$0x28 #pass diff --git a/gas/testsuite/gas/i386/lfence-ret-c.d b/gas/testsuite/gas/i386/lfence-ret-c.d new file mode 100644 index 00000000000..fceb0eb182a --- /dev/null +++ b/gas/testsuite/gas/i386/lfence-ret-c.d @@ -0,0 +1,35 @@ +#source: lfence-ret.s +#as: -mlfence-before-ret=or -mlfence-before-indirect-branch=all +#objdump: -dw + +.*: +file format .* + + +Disassembly of section .text: + +0+ <_start>: + +[a-f0-9]+: 66 83 0c 24 00 orw \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c3 retw + +[a-f0-9]+: 66 83 0c 24 00 orw \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c2 14 00 retw \$0x14 + +[a-f0-9]+: 83 0c 24 00 orl \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: c3 ret + +[a-f0-9]+: 83 0c 24 00 orl \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: c2 1e 00 ret \$0x1e + +[a-f0-9]+: 66 83 0c 24 00 orw \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 cb lretw + +[a-f0-9]+: 66 83 0c 24 00 orw \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 ca 28 00 lretw \$0x28 + +[a-f0-9]+: 83 0c 24 00 orl \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: cb lret + +[a-f0-9]+: 83 0c 24 00 orl \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: ca 28 00 lret \$0x28 +#pass diff --git a/gas/testsuite/gas/i386/lfence-ret-d.d b/gas/testsuite/gas/i386/lfence-ret-d.d new file mode 100644 index 00000000000..03f8f88fd7b --- /dev/null +++ b/gas/testsuite/gas/i386/lfence-ret-d.d @@ -0,0 +1,36 @@ +#source: lfence-ret.s +#as: -mlfence-before-ret=shl +#objdump: -dw +#name: -mlfence-before-ret=shl + +.*: +file format .* + + +Disassembly of section .text: + +0+ <_start>: + +[a-f0-9]+: 66 c1 24 24 00 shlw \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c3 retw + +[a-f0-9]+: 66 c1 24 24 00 shlw \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c2 14 00 retw \$0x14 + +[a-f0-9]+: c1 24 24 00 shll \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: c3 ret + +[a-f0-9]+: c1 24 24 00 shll \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: c2 1e 00 ret \$0x1e + +[a-f0-9]+: 66 c1 24 24 00 shlw \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 cb lretw + +[a-f0-9]+: 66 c1 24 24 00 shlw \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 ca 28 00 lretw \$0x28 + +[a-f0-9]+: c1 24 24 00 shll \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: cb lret + +[a-f0-9]+: c1 24 24 00 shll \$0x0,\(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: ca 28 00 lret \$0x28 +#pass diff --git a/gas/testsuite/gas/i386/lfence-ret.s b/gas/testsuite/gas/i386/lfence-ret.s index 35c4e6eeaad..f27fa5839e5 100644 --- a/gas/testsuite/gas/i386/lfence-ret.s +++ b/gas/testsuite/gas/i386/lfence-ret.s @@ -1,4 +1,10 @@ .text _start: + retw + retw $20 ret ret $30 + lretw + lretw $40 + lret + lret $40 diff --git a/gas/testsuite/gas/i386/x86-64-lfence-load.d b/gas/testsuite/gas/i386/x86-64-lfence-load.d index 4f6cd00edf1..5cd764391d1 100644 --- a/gas/testsuite/gas/i386/x86-64-lfence-load.d +++ b/gas/testsuite/gas/i386/x86-64-lfence-load.d @@ -1,5 +1,6 @@ #as: -mlfence-after-load=yes #objdump: -dw +#warning_output: lfence-load.e #name: x86-64 -mlfence-after-load=yes .*: +file format .* @@ -15,6 +16,29 @@ Disassembly of section .text: +[a-f0-9]+: 0f c7 75 00 vmptrld 0x0\(%rbp\) +[a-f0-9]+: 0f ae e8 lfence +[a-f0-9]+: 66 0f c7 75 00 vmclear 0x0\(%rbp\) + +[a-f0-9]+: 66 0f 38 82 55 00 invpcid 0x0\(%rbp\),%rdx + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 67 0f 01 38 invlpg \(%eax\) + +[a-f0-9]+: 0f ae 7d 00 clflush 0x0\(%rbp\) + +[a-f0-9]+: 66 0f ae 7d 00 clflushopt 0x0\(%rbp\) + +[a-f0-9]+: 66 0f ae 75 00 clwb 0x0\(%rbp\) + +[a-f0-9]+: 0f 1c 45 00 cldemote 0x0\(%rbp\) + +[a-f0-9]+: f3 0f 1b 4d 00 bndmk 0x0\(%rbp\),%bnd1 + +[a-f0-9]+: f3 0f 1a 4d 00 bndcl 0x0\(%rbp\),%bnd1 + +[a-f0-9]+: f2 0f 1a 4d 00 bndcu 0x0\(%rbp\),%bnd1 + +[a-f0-9]+: f2 0f 1b 4d 00 bndcn 0x0\(%rbp\),%bnd1 + +[a-f0-9]+: 0f 1b 4d 00 bndstx %bnd1,0x0\(%rbp\) + +[a-f0-9]+: 0f 1a 4d 00 bndldx 0x0\(%rbp\),%bnd1 + +[a-f0-9]+: 0f 18 4d 00 prefetcht0 0x0\(%rbp\) + +[a-f0-9]+: 0f 18 55 00 prefetcht1 0x0\(%rbp\) + +[a-f0-9]+: 0f 18 5d 00 prefetcht2 0x0\(%rbp\) + +[a-f0-9]+: 0f 0d 4d 00 prefetchw 0x0\(%rbp\) + +[a-f0-9]+: 0f a1 popq %fs + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 9d popfq + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: d7 xlat %ds:\(%rbx\) + +[a-f0-9]+: 0f ae e8 lfence +[a-f0-9]+: d9 55 00 fsts 0x0\(%rbp\) +[a-f0-9]+: d9 45 00 flds 0x0\(%rbp\) +[a-f0-9]+: 0f ae e8 lfence diff --git a/gas/testsuite/gas/i386/x86-64-lfence-load.s b/gas/testsuite/gas/i386/x86-64-lfence-load.s index 76d08866179..2a3ac6b7d2d 100644 --- a/gas/testsuite/gas/i386/x86-64-lfence-load.s +++ b/gas/testsuite/gas/i386/x86-64-lfence-load.s @@ -4,6 +4,25 @@ _start: lgdt (%rbp) vmptrld (%rbp) vmclear (%rbp) + invpcid (%rbp), %rdx + invlpg (%eax) + clflush (%rbp) + clflushopt (%rbp) + clwb (%rbp) + cldemote (%rbp) + bndmk (%rbp), %bnd1 + bndcl (%rbp), %bnd1 + bndcu (%rbp), %bnd1 + bndcn (%rbp), %bnd1 + bndstx %bnd1, (%rbp) + bndldx (%rbp), %bnd1 + prefetcht0 (%rbp) + prefetcht1 (%rbp) + prefetcht2 (%rbp) + prefetchw (%rbp) + pop %fs + popf + xlatb (%rbx) fsts (%rbp) flds (%rbp) fistl (%rbp) diff --git a/gas/testsuite/gas/i386/x86-64-lfence-ret-a.d b/gas/testsuite/gas/i386/x86-64-lfence-ret-a.d index 26e5b48bec3..345217b17c7 100644 --- a/gas/testsuite/gas/i386/x86-64-lfence-ret-a.d +++ b/gas/testsuite/gas/i386/x86-64-lfence-ret-a.d @@ -1,6 +1,7 @@ -#source: lfence-ret.s +#source: x86-64-lfence-ret.s #as: -mlfence-before-ret=or -#objdump: -dw +#warning_output: x86-64-lfence-ret.e +#objdump: -dw -Mintel64 #name: x86-64 -mlfence-before-ret=or .*: +file format .* @@ -9,10 +10,40 @@ Disassembly of section .text: 0+ <_start>: + +[a-f0-9]+: 48 83 0c 24 00 orq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c3 data16 retq + +[a-f0-9]+: 48 83 0c 24 00 orq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c2 14 00 data16 retq \$0x14 +[a-f0-9]+: 48 83 0c 24 00 orq \$0x0,\(%rsp\) +[a-f0-9]+: 0f ae e8 lfence +[a-f0-9]+: c3 retq +[a-f0-9]+: 48 83 0c 24 00 orq \$0x0,\(%rsp\) +[a-f0-9]+: 0f ae e8 lfence +[a-f0-9]+: c2 1e 00 retq \$0x1e + +[a-f0-9]+: 48 83 0c 24 00 orq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 48 c3 data16 rex.W retq + +[a-f0-9]+: 48 83 0c 24 00 orq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 48 c2 28 00 data16 rex.W retq \$0x28 + +[a-f0-9]+: 66 83 0c 24 00 orw \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 cb lretw + +[a-f0-9]+: 66 83 0c 24 00 orw \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 ca 28 00 lretw \$0x28 + +[a-f0-9]+: 83 0c 24 00 orl \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: cb lret + +[a-f0-9]+: 83 0c 24 00 orl \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: ca 28 00 lret \$0x28 + +[a-f0-9]+: 48 83 0c 24 00 orq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 48 cb lretq + +[a-f0-9]+: 48 83 0c 24 00 orq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 48 ca 28 00 lretq \$0x28 #pass diff --git a/gas/testsuite/gas/i386/x86-64-lfence-ret-b.d b/gas/testsuite/gas/i386/x86-64-lfence-ret-b.d index 340488831de..3947660fea8 100644 --- a/gas/testsuite/gas/i386/x86-64-lfence-ret-b.d +++ b/gas/testsuite/gas/i386/x86-64-lfence-ret-b.d @@ -1,6 +1,7 @@ -#source: lfence-ret.s +#source: x86-64-lfence-ret.s #as: -mlfence-before-ret=not -#objdump: -dw +#warning_output: x86-64-lfence-ret.e +#objdump: -dw -Mintel64 #name: x86-64 -mlfence-before-ret=not .*: +file format .* @@ -9,6 +10,14 @@ Disassembly of section .text: 0+ <_start>: + +[a-f0-9]+: 48 f7 14 24 notq \(%rsp\) + +[a-f0-9]+: 48 f7 14 24 notq \(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c3 data16 retq + +[a-f0-9]+: 48 f7 14 24 notq \(%rsp\) + +[a-f0-9]+: 48 f7 14 24 notq \(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c2 14 00 data16 retq \$0x14 +[a-f0-9]+: 48 f7 14 24 notq \(%rsp\) +[a-f0-9]+: 48 f7 14 24 notq \(%rsp\) +[a-f0-9]+: 0f ae e8 lfence @@ -17,4 +26,36 @@ Disassembly of section .text: +[a-f0-9]+: 48 f7 14 24 notq \(%rsp\) +[a-f0-9]+: 0f ae e8 lfence +[a-f0-9]+: c2 1e 00 retq \$0x1e + +[a-f0-9]+: 48 f7 14 24 notq \(%rsp\) + +[a-f0-9]+: 48 f7 14 24 notq \(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 48 c3 data16 rex.W retq + +[a-f0-9]+: 48 f7 14 24 notq \(%rsp\) + +[a-f0-9]+: 48 f7 14 24 notq \(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 48 c2 28 00 data16 rex.W retq \$0x28 + +[a-f0-9]+: 66 f7 14 24 notw \(%rsp\) + +[a-f0-9]+: 66 f7 14 24 notw \(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 cb lretw + +[a-f0-9]+: 66 f7 14 24 notw \(%rsp\) + +[a-f0-9]+: 66 f7 14 24 notw \(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 ca 28 00 lretw \$0x28 + +[a-f0-9]+: f7 14 24 notl \(%rsp\) + +[a-f0-9]+: f7 14 24 notl \(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: cb lret + +[a-f0-9]+: f7 14 24 notl \(%rsp\) + +[a-f0-9]+: f7 14 24 notl \(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: ca 28 00 lret \$0x28 + +[a-f0-9]+: 48 f7 14 24 notq \(%rsp\) + +[a-f0-9]+: 48 f7 14 24 notq \(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 48 cb lretq + +[a-f0-9]+: 48 f7 14 24 notq \(%rsp\) + +[a-f0-9]+: 48 f7 14 24 notq \(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 48 ca 28 00 lretq \$0x28 #pass diff --git a/gas/testsuite/gas/i386/x86-64-lfence-ret-c.d b/gas/testsuite/gas/i386/x86-64-lfence-ret-c.d new file mode 100644 index 00000000000..cd89a95bc43 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-lfence-ret-c.d @@ -0,0 +1,48 @@ +#source: x86-64-lfence-ret.s +#as: -mlfence-before-ret=or -mlfence-before-indirect-branch=all +#warning_output: x86-64-lfence-ret.e +#objdump: -dw -Mintel64 + +.*: +file format .* + + +Disassembly of section .text: + +0+ <_start>: + +[a-f0-9]+: 48 83 0c 24 00 orq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c3 data16 retq + +[a-f0-9]+: 48 83 0c 24 00 orq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c2 14 00 data16 retq \$0x14 + +[a-f0-9]+: 48 83 0c 24 00 orq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: c3 retq + +[a-f0-9]+: 48 83 0c 24 00 orq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: c2 1e 00 retq \$0x1e + +[a-f0-9]+: 48 83 0c 24 00 orq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 48 c3 data16 rex.W retq + +[a-f0-9]+: 48 83 0c 24 00 orq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 48 c2 28 00 data16 rex.W retq \$0x28 + +[a-f0-9]+: 66 83 0c 24 00 orw \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 cb lretw + +[a-f0-9]+: 66 83 0c 24 00 orw \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 ca 28 00 lretw \$0x28 + +[a-f0-9]+: 83 0c 24 00 orl \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: cb lret + +[a-f0-9]+: 83 0c 24 00 orl \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: ca 28 00 lret \$0x28 + +[a-f0-9]+: 48 83 0c 24 00 orq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 48 cb lretq + +[a-f0-9]+: 48 83 0c 24 00 orq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 48 ca 28 00 lretq \$0x28 +#pass diff --git a/gas/testsuite/gas/i386/x86-64-lfence-ret-d.d b/gas/testsuite/gas/i386/x86-64-lfence-ret-d.d new file mode 100644 index 00000000000..593b8894359 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-lfence-ret-d.d @@ -0,0 +1,49 @@ +#source: x86-64-lfence-ret.s +#as: -mlfence-before-ret=shl +#warning_output: x86-64-lfence-ret.e +#objdump: -dw -Mintel64 +#name: x86-64 -mlfence-before-ret=shl + +.*: +file format .* + + +Disassembly of section .text: + +0+ <_start>: + +[a-f0-9]+: 48 c1 24 24 00 shlq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c3 data16 retq + +[a-f0-9]+: 48 c1 24 24 00 shlq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c2 14 00 data16 retq \$0x14 + +[a-f0-9]+: 48 c1 24 24 00 shlq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: c3 retq + +[a-f0-9]+: 48 c1 24 24 00 shlq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: c2 1e 00 retq \$0x1e + +[a-f0-9]+: 48 c1 24 24 00 shlq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 48 c3 data16 rex.W retq + +[a-f0-9]+: 48 c1 24 24 00 shlq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 48 c2 28 00 data16 rex.W retq \$0x28 + +[a-f0-9]+: 66 c1 24 24 00 shlw \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 cb lretw + +[a-f0-9]+: 66 c1 24 24 00 shlw \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 ca 28 00 lretw \$0x28 + +[a-f0-9]+: c1 24 24 00 shll \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: cb lret + +[a-f0-9]+: c1 24 24 00 shll \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: ca 28 00 lret \$0x28 + +[a-f0-9]+: 48 c1 24 24 00 shlq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 48 cb lretq + +[a-f0-9]+: 48 c1 24 24 00 shlq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 48 ca 28 00 lretq \$0x28 +#pass diff --git a/gas/testsuite/gas/i386/x86-64-lfence-ret-e.d b/gas/testsuite/gas/i386/x86-64-lfence-ret-e.d new file mode 100644 index 00000000000..b4d229654cd --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-lfence-ret-e.d @@ -0,0 +1,49 @@ +#source: x86-64-lfence-ret.s +#as: -mlfence-before-ret=shl +#warning_output: x86-64-lfence-ret.e +#objdump: -dw -Mintel64 +#name: x86-64 -mlfence-before-ret=yes + +.*: +file format .* + + +Disassembly of section .text: + +0+ <_start>: + +[a-f0-9]+: 48 c1 24 24 00 shlq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c3 data16 retq + +[a-f0-9]+: 48 c1 24 24 00 shlq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c2 14 00 data16 retq \$0x14 + +[a-f0-9]+: 48 c1 24 24 00 shlq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: c3 retq + +[a-f0-9]+: 48 c1 24 24 00 shlq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: c2 1e 00 retq \$0x1e + +[a-f0-9]+: 48 c1 24 24 00 shlq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 48 c3 data16 rex.W retq + +[a-f0-9]+: 48 c1 24 24 00 shlq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 48 c2 28 00 data16 rex.W retq \$0x28 + +[a-f0-9]+: 66 c1 24 24 00 shlw \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 cb lretw + +[a-f0-9]+: 66 c1 24 24 00 shlw \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 ca 28 00 lretw \$0x28 + +[a-f0-9]+: c1 24 24 00 shll \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: cb lret + +[a-f0-9]+: c1 24 24 00 shll \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: ca 28 00 lret \$0x28 + +[a-f0-9]+: 48 c1 24 24 00 shlq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 48 cb lretq + +[a-f0-9]+: 48 c1 24 24 00 shlq \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 48 ca 28 00 lretq \$0x28 +#pass diff --git a/gas/testsuite/gas/i386/x86-64-lfence-ret.e b/gas/testsuite/gas/i386/x86-64-lfence-ret.e new file mode 100644 index 00000000000..13730e50e6f --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-lfence-ret.e @@ -0,0 +1,3 @@ +.*: Assembler messages: +.*:??: Warning: no instruction mnemonic suffix given and no register operands; using default for `lret' +.*:??: Warning: no instruction mnemonic suffix given and no register operands; using default for `lret' diff --git a/gas/testsuite/gas/i386/x86-64-lfence-ret.s b/gas/testsuite/gas/i386/x86-64-lfence-ret.s new file mode 100644 index 00000000000..986239c222e --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-lfence-ret.s @@ -0,0 +1,14 @@ + .text +_start: + retw + retw $20 + ret + ret $30 + data16 rex.w ret + data16 rex.w ret $40 + lretw + lretw $40 + lret + lret $40 + lretq + lretq $40