[PATCH 1/2] i386: Generate lfence with load/indirect branch/ret [CVE-2020-0551]
Hongtao Liu
crazylht@gmail.com
Wed Apr 22 03:33:25 GMT 2020
More information about the Binutils mailing list
Wed Apr 22 03:33:25 GMT 2020
- Previous message (by thread): [PATCH 1/2] i386: Generate lfence with load/indirect branch/ret [CVE-2020-0551]
- Next message (by thread): [PATCH 1/2] i386: Generate lfence with load/indirect branch/ret [CVE-2020-0551]
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Tue, Apr 21, 2020 at 2:30 PM Jan Beulich <jbeulich@suse.com> wrote: > > On 21.04.2020 04:24, Hongtao Liu wrote: > > On Mon, Apr 20, 2020 at 3:34 PM Jan Beulich <jbeulich@suse.com> wrote: > >> > >> On 20.04.2020 09:20, Hongtao Liu wrote: > >>> On Thu, Apr 16, 2020 at 4:33 PM Jan Beulich <jbeulich@suse.com> wrote: > >>>> On 16.04.2020 07:34, Hongtao Liu wrote: > >>>>> @@ -4506,6 +4520,22 @@ insert_lfence_after (void) > >>>>> { > >>>>> if (lfence_after_load && load_insn_p ()) > >>>>> { > >>>>> + /* Insert lfence after rep cmps/scas only under > >>>>> + -mlfence-after-load=all. */ > >>>>> + if (((i.tm.base_opcode | 0x1) == 0xa7 > >>>>> + || (i.tm.base_opcode | 0x1) == 0xaf) > >>>>> + && i.prefix[REP_PREFIX]) > >>>> > >>>> I'm afraid I don't understand why the REP forms need treating > >>>> differently from the non-REP ones of the same insns. > >>>> > >>> > >>> Not all REP forms, just REP CMPS/SCAS which would change EFLAGS. > >> > >> Well, of course just the two. But this doesn't answer my question > >> as to why there is such a special case. > >> > > > > 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. The > > solution is to unfold any REP CMPS and REP SCAS operations into a loop > > and insert an LFENCE after the CMPS/SCAS instruction. For example, > > REPNZ SCAS can be unfolded to: > > > > .RepLoop: > > JRCXZ .ExitRepLoop > > DEC rcx # or ecx if the REPNZ SCAS uses a 32-bit address size > > SCAS > > LFENCE > > JNZ .RepLoop > > .ExitRepLoop: > > ... > > > > The request i get is to add options to handle or not handle REP > > CMPS/SCAS also plus issue a warning. > > But you don't handle them as per what you've written above, afaics. > Am I overlooking anything? > Well, that solution is not meant for gas, i put them here for convienence of understanding of why we need to handle REP CMPS/SCAS specially. > > @@ -647,7 +656,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 +4360,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. */ > > Bad indentation (also elsewhere, so this may be an issue with your > mail client)? > Yes, tab is ignored when copy into gmail(plain text mode). I need to manually replace tab with 8 space. > > @@ -4536,8 +4577,8 @@ insert_lfence_before (void) > > > > if (i.reg_operands == 1) > > { > > - /* Indirect branch via register. Don't insert lfence with > > - -mlfence-after-load=yes. */ > > + /* Indirect branch via register. Insert lfence when > > + -mlfence-after-load=none. */ > > if (lfence_after_load > > || lfence_before_indirect_branch == lfence_branch_memory) > > return; > > The changed comment is awkward to read - the reader will almost > certainly wonder why "none" implies an action. I think you either > want to explain this further, or revert back to the original form > by simply making it "... with -mlfence-after-load={all,general}." > Changed. > > @@ -4568,12 +4609,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 +4625,50 @@ 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 > > + > > + char prefix = i.prefix[DATA_PREFIX] && !(i.prefix[REX_PREFIX] & REX_W) > > + ? 0x66 : flag_code == CODE_64BIT ? 0x48 : 0x0; > > While this now looks better, it's tailored to near RET. Far RET > as well as IRET default to 32-bit operand size in 64-bit mode. > I can't tell how relevant it is to match effective operand size > of the guarded and guarding insns. > Changed Update patch. >From 26d23fc18e090799872057bec21831c02e8b5d03 Mon Sep 17 00:00:00 2001 From: liuhongt <hongtao.liu@intel.com> Date: Mon, 16 Mar 2020 11:03:12 +0800 Subject: [PATCH] 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. Ajust -mlfence-after-load=[yes/no] to -mlfence-after-load=[none|general|all]. -mlfence-after-load=[none/all] equal original -mlfence-after-load=[no/yes], -mlfence-after-load=general won't add lfence after REP CMPS/SCAS since they would affect control flow behavior. -mlfence-after-load=all will issue an warning when adding lfence after REP CMPS/SCAS. 4. Adjust testcases and documents. gas/Changelog: * config/tc-i386.c (lfence_after_load) Deleted. (lfence_after_load_kind): New. (lfence_before_ret_shl): New member. (load_insn_p): implict load for POP/POPA/POPF/XLATB, no load for Anysize insns. (insert_after_load): Handle specially 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-after-load=[yes|no] to -mlfence-after-load=[none|general|all], 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. --- gas/config/tc-i386.c | 154 +++++++++++++----- gas/doc/c-i386.texi | 31 ++-- gas/testsuite/gas/i386/i386.exp | 7 + gas/testsuite/gas/i386/lfence-load-b.d | 137 ++++++++++++++++ gas/testsuite/gas/i386/lfence-load-b.e | 3 + gas/testsuite/gas/i386/lfence-load.d | 30 +++- gas/testsuite/gas/i386/lfence-load.e | 3 + gas/testsuite/gas/i386/lfence-load.s | 20 +++ gas/testsuite/gas/i386/lfence-ret-a.d | 18 ++ gas/testsuite/gas/i386/lfence-ret-b.d | 24 +++ gas/testsuite/gas/i386/lfence-ret-c.d | 35 ++++ gas/testsuite/gas/i386/lfence-ret-d.d | 36 ++++ gas/testsuite/gas/i386/lfence-ret.s | 6 + gas/testsuite/gas/i386/x86-64-lfence-load-b.d | 137 ++++++++++++++++ gas/testsuite/gas/i386/x86-64-lfence-load.d | 28 +++- gas/testsuite/gas/i386/x86-64-lfence-load.s | 19 +++ gas/testsuite/gas/i386/x86-64-lfence-ret-a.d | 33 +++- gas/testsuite/gas/i386/x86-64-lfence-ret-b.d | 43 ++++- gas/testsuite/gas/i386/x86-64-lfence-ret-c.d | 48 ++++++ gas/testsuite/gas/i386/x86-64-lfence-ret-d.d | 49 ++++++ gas/testsuite/gas/i386/x86-64-lfence-ret-e.d | 49 ++++++ gas/testsuite/gas/i386/x86-64-lfence-ret.e | 3 + gas/testsuite/gas/i386/x86-64-lfence-ret.s | 14 ++ 23 files changed, 870 insertions(+), 57 deletions(-) create mode 100644 gas/testsuite/gas/i386/lfence-load-b.d create mode 100644 gas/testsuite/gas/i386/lfence-load-b.e create mode 100644 gas/testsuite/gas/i386/lfence-load.e create mode 100644 gas/testsuite/gas/i386/lfence-ret-c.d create mode 100644 gas/testsuite/gas/i386/lfence-ret-d.d create mode 100644 gas/testsuite/gas/i386/x86-64-lfence-load-b.d create mode 100644 gas/testsuite/gas/i386/x86-64-lfence-ret-c.d create mode 100644 gas/testsuite/gas/i386/x86-64-lfence-ret-d.d create mode 100644 gas/testsuite/gas/i386/x86-64-lfence-ret-e.d create mode 100644 gas/testsuite/gas/i386/x86-64-lfence-ret.e create mode 100644 gas/testsuite/gas/i386/x86-64-lfence-ret.s diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 093497becd..7454f2987f 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -629,8 +629,17 @@ static int omit_lock_prefix = 0; "lock addl $0, (%{re}sp)". */ static int avoid_fence = 0; -/* 1 if lfence should be inserted after every load. */ -static int lfence_after_load = 0; +/* Non-zero if lfence should be inserted after load. + lfence_load_all will generate lfence for all load instructions, + lfence_load_general will generate lfence for all + load instruction except REP CMPS/SCAS. */ +static enum lfence_after_load_kind + { + lfence_load_none = 0, + lfence_load_general, + lfence_load_all + } +lfence_after_load; /* Non-zero if lfence should be inserted before indirect branch. */ static enum lfence_before_indirect_branch_kind @@ -647,7 +656,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 +4360,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 +4522,31 @@ insert_lfence_after (void) { if (lfence_after_load && load_insn_p ()) { + /* Insert lfence after rep cmps/scas only under + -mlfence-after-load=all. */ + /* 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]) + { + if (lfence_after_load == lfence_load_general) + { + as_warn (_("`%s` skips -mlfence-after-load=general"), + i.tm.name); + return; + } + else + as_warn (_("`%s` changes flags which would affect control flow behavior"), + i.tm.name); + } char *p = frag_more (3); *p++ = 0xf; *p++ = 0xae; @@ -4536,8 +4577,8 @@ insert_lfence_before (void) if (i.reg_operands == 1) { - /* Indirect branch via register. Don't insert lfence with - -mlfence-after-load=yes. */ + /* Indirect branch via register. Don't insert lfence with + -mlfence-after-load={general,all}. */ if (lfence_after_load || lfence_before_indirect_branch == lfence_branch_memory) return; @@ -4568,12 +4609,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 +4625,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; - } + + bfd_boolean lret = (i.tm.base_opcode | 0x1) == 0xcb; + 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. */ + if (has_rexw) + prefix = 0x48; else + prefix = i.prefix[DATA_PREFIX] + ? 0x66 + : !lret && flag_code == CODE_64BIT ? 0x48 : 0x0; + + if (lfence_before_ret == lfence_before_ret_not) { - p = frag_more ((flag_code == CODE_64BIT ? 2 : 0) + 6 + 3); - /* notl: 0xf71424. */ - if (flag_code == CODE_64BIT) - *p++ = 0x48; + /* not: 0xf71424, may add prefix + for operand size overwrite 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 overwrite or 64-bit code. */ + *p++ = 0x83; + *p++ = 0x0c; + } + else + { + /* shl: 0xc1242400, may add prefix + for operand size overwrite or 64-bit code. */ + *p++ = 0xc1; + *p++ = 0x24; + } + + *p++ = 0x24; + *p++ = 0x0; + } + *p++ = 0xf; *p++ = 0xae; *p = 0xe8; @@ -12985,17 +13053,23 @@ md_parse_option (int c, const char *arg) break; case OPTION_MLFENCE_AFTER_LOAD: - if (strcasecmp (arg, "yes") == 0) - lfence_after_load = 1; - else if (strcasecmp (arg, "no") == 0) - lfence_after_load = 0; + if (strcasecmp (arg, "general") == 0) + lfence_after_load = lfence_load_general; + else if (strcasecmp (arg, "all") == 0) + lfence_after_load = lfence_load_all; + else if (strcasecmp (arg, "none") == 0) + lfence_after_load = lfence_load_none; else as_fatal (_("invalid -mlfence-after-load= option: `%s'"), arg); break; 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 +13086,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 @@ -13376,13 +13452,13 @@ md_show_usage (FILE *stream) -mbranches-within-32B-boundaries\n\ align branches within 32 byte boundary\n")); fprintf (stream, _("\ - -mlfence-after-load=[no|yes] (default: no)\n\ + -mlfence-after-load=[none|general|all] (default: none)\n\ generate lfence after load\n")); fprintf (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 628fb1ad5a..19a4bf874e 100644 --- a/gas/doc/c-i386.texi +++ b/gas/doc/c-i386.texi @@ -470,12 +470,15 @@ The default doesn't align branches. @cindex @samp{-mlfence-after-load=} option, i386 @cindex @samp{-mlfence-after-load=} option, x86-64 -@item -mlfence-after-load=@var{no} -@itemx -mlfence-after-load=@var{yes} +@item -mlfence-after-load=@var{none} +@item -mlfence-after-load=@var{general} +@itemx -mlfence-after-load=@var{all} These options control whether the assembler should generate lfence -after load instructions. @option{-mlfence-after-load=@var{yes}} will -generate lfence. @option{-mlfence-after-load=@var{no}} will not generate -lfence, which is the default. +after load instructions. @option{-mlfence-after-load=@var{all}} will +generate lfence for all load instructions, +@option{-mlfence-after-load=@var{general}}will generate lfence for all +load instruction except rep cmps/scas, @option{-mlfence-after-load=@var{none}} +will not generate lfence, which is the default. @cindex @samp{-mlfence-before-indirect-branch=} option, i386 @cindex @samp{-mlfence-before-indirect-branch=} option, x86-64 @@ -488,28 +491,32 @@ 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 warning before indirect near branch via memory. @option{-mlfence-before-indirect-branch=@var{none}} will not generate -lfence nor issue warning, which is the default. Note that lfence won't -be generated before indirect near branch via register with -@option{-mlfence-after-load=@var{yes}} since lfence will be generated +lfence nor issue warning, which is the default. Note that lfence will +generate before indirect near branch via register only with +@option{-mlfence-after-load=@var{none}} since lfence will be generated 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 9dacc11906..bb3897b9ad 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -530,11 +530,14 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]] run_dump_test "align-branch-8" run_dump_test "align-branch-9" run_dump_test "lfence-load" + run_dump_test "lfence-load-b" run_dump_test "lfence-indbr-a" run_dump_test "lfence-indbr-b" 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, @@ -1117,11 +1120,15 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t run_dump_test "x86-64-align-branch-8" run_dump_test "x86-64-align-branch-9" run_dump_test "x86-64-lfence-load" + run_dump_test "x86-64-lfence-load-b" run_dump_test "x86-64-lfence-indbr-a" run_dump_test "x86-64-lfence-indbr-b" 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-b.d b/gas/testsuite/gas/i386/lfence-load-b.d new file mode 100644 index 0000000000..b4f7bc0f19 --- /dev/null +++ b/gas/testsuite/gas/i386/lfence-load-b.d @@ -0,0 +1,137 @@ +#source: lfence-load.s +#as: -mlfence-after-load=general +#objdump: -dw +#warning_output: lfence-load-b.e +#name: lfence-load-b + +.*: +file format .* + + +Disassembly of section .text: + +0+ <_start>: + +[a-f0-9]+: c5 f8 ae 55 00 vldmxcsr 0x0\(%ebp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 0f 01 55 00 lgdtl 0x0\(%ebp\) + +[a-f0-9]+: 0f ae e8 lfence + +[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 + +[a-f0-9]+: db 55 00 fistl 0x0\(%ebp\) + +[a-f0-9]+: df 55 00 fists 0x0\(%ebp\) + +[a-f0-9]+: db 45 00 fildl 0x0\(%ebp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: df 45 00 filds 0x0\(%ebp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 9b dd 75 00 fsave 0x0\(%ebp\) + +[a-f0-9]+: dd 65 00 frstor 0x0\(%ebp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: df 45 00 filds 0x0\(%ebp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: df 4d 00 fisttps 0x0\(%ebp\) + +[a-f0-9]+: d9 65 00 fldenv 0x0\(%ebp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 9b d9 75 00 fstenv 0x0\(%ebp\) + +[a-f0-9]+: d8 45 00 fadds 0x0\(%ebp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: d8 04 24 fadds \(%esp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: d8 c3 fadd %st\(3\),%st + +[a-f0-9]+: d8 01 fadds \(%ecx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: df 01 filds \(%ecx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: df 11 fists \(%ecx\) + +[a-f0-9]+: 0f ae 29 xrstor \(%ecx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 0f 18 01 prefetchnta \(%ecx\) + +[a-f0-9]+: 0f c7 09 cmpxchg8b \(%ecx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 41 inc %ecx + +[a-f0-9]+: 0f 01 10 lgdtl \(%eax\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 0f 0f 66 02 b0 pfcmpeq 0x2\(%esi\),%mm4 + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 8f 00 popl \(%eax\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 58 pop %eax + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 d1 11 rclw \(%ecx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: f7 01 01 00 00 00 testl \$0x1,\(%ecx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: ff 01 incl \(%ecx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: f7 11 notl \(%ecx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: f7 31 divl \(%ecx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: f7 21 mull \(%ecx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: f7 39 idivl \(%ecx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: f7 29 imull \(%ecx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 8d 04 40 lea \(%eax,%eax,2\),%eax + +[a-f0-9]+: c9 leave + +[a-f0-9]+: 6e outsb %ds:\(%esi\),\(%dx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: ac lods %ds:\(%esi\),%al + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: f3 a5 rep movsl %ds:\(%esi\),%es:\(%edi\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: f3 af repz scas %es:\(%edi\),%eax + +[a-f0-9]+: f3 a7 repz cmpsl %es:\(%edi\),%ds:\(%esi\) + +[a-f0-9]+: f3 ad rep lods %ds:\(%esi\),%eax + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 83 00 01 addl \$0x1,\(%eax\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 0f ba 20 01 btl \$0x1,\(%eax\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 0f c1 03 xadd %eax,\(%ebx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 0f c1 c3 xadd %eax,%ebx + +[a-f0-9]+: 87 03 xchg %eax,\(%ebx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 93 xchg %eax,%ebx + +[a-f0-9]+: 39 45 40 cmp %eax,0x40\(%ebp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 3b 45 40 cmp 0x40\(%ebp\),%eax + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 01 45 40 add %eax,0x40\(%ebp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 03 00 add \(%eax\),%eax + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 85 45 40 test %eax,0x40\(%ebp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 85 45 40 test %eax,0x40\(%ebp\) + +[a-f0-9]+: 0f ae e8 lfence +#pass diff --git a/gas/testsuite/gas/i386/lfence-load-b.e b/gas/testsuite/gas/i386/lfence-load-b.e new file mode 100644 index 0000000000..c394e02296 --- /dev/null +++ b/gas/testsuite/gas/i386/lfence-load-b.e @@ -0,0 +1,3 @@ +.*: Assembler messages: +.*:??: Warning: `scas` skips -mlfence-after-load=general +.*:??: Warning: `cmps` skips -mlfence-after-load=general \ No newline at end of file diff --git a/gas/testsuite/gas/i386/lfence-load.d b/gas/testsuite/gas/i386/lfence-load.d index cd7e7f76df..273e302f38 100644 --- a/gas/testsuite/gas/i386/lfence-load.d +++ b/gas/testsuite/gas/i386/lfence-load.d @@ -1,6 +1,7 @@ -#as: -mlfence-after-load=yes +#as: -mlfence-after-load=all #objdump: -dw -#name: -mlfence-after-load=yes +#warning_output: lfence-load.e +#name: -mlfence-after-load=all .*: +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 0000000000..1ee49da7fd --- /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 b417ac644e..4b4aa1610b 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 719cf1b472..aa35857664 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 e3914b9c28..77001c425e 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 0000000000..fceb0eb182 --- /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 0000000000..03f8f88fd7 --- /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 35c4e6eeaa..f27fa5839e 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-b.d b/gas/testsuite/gas/i386/x86-64-lfence-load-b.d new file mode 100644 index 0000000000..b1fd3cad42 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-lfence-load-b.d @@ -0,0 +1,137 @@ +#source: x86-64-lfence-load.s +#as: -mlfence-after-load=general +#objdump: -dw +#warning_output: lfence-load-b.e +#name: x86-64 lfence-load-b + +.*: +file format .* + + +Disassembly of section .text: + +0+ <_start>: + +[a-f0-9]+: c5 f8 ae 55 00 vldmxcsr 0x0\(%rbp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 0f 01 55 00 lgdt 0x0\(%rbp\) + +[a-f0-9]+: 0f ae e8 lfence + +[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 + +[a-f0-9]+: db 55 00 fistl 0x0\(%rbp\) + +[a-f0-9]+: df 55 00 fists 0x0\(%rbp\) + +[a-f0-9]+: db 45 00 fildl 0x0\(%rbp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: df 45 00 filds 0x0\(%rbp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 9b dd 75 00 fsave 0x0\(%rbp\) + +[a-f0-9]+: dd 65 00 frstor 0x0\(%rbp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: df 45 00 filds 0x0\(%rbp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: df 4d 00 fisttps 0x0\(%rbp\) + +[a-f0-9]+: d9 65 00 fldenv 0x0\(%rbp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 9b d9 75 00 fstenv 0x0\(%rbp\) + +[a-f0-9]+: d8 45 00 fadds 0x0\(%rbp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: d8 04 24 fadds \(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: d8 c3 fadd %st\(3\),%st + +[a-f0-9]+: d8 01 fadds \(%rcx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: df 01 filds \(%rcx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: df 11 fists \(%rcx\) + +[a-f0-9]+: 0f ae 29 xrstor \(%rcx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 0f 18 01 prefetchnta \(%rcx\) + +[a-f0-9]+: 0f c7 09 cmpxchg8b \(%rcx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 48 0f c7 09 cmpxchg16b \(%rcx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: ff c1 inc %ecx + +[a-f0-9]+: 0f 01 10 lgdt \(%rax\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 0f 0f 66 02 b0 pfcmpeq 0x2\(%rsi\),%mm4 + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 8f 00 popq \(%rax\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 58 pop %rax + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 d1 11 rclw \(%rcx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: f7 01 01 00 00 00 testl \$0x1,\(%rcx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: ff 01 incl \(%rcx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: f7 11 notl \(%rcx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: f7 31 divl \(%rcx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: f7 21 mull \(%rcx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: f7 39 idivl \(%rcx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: f7 29 imull \(%rcx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 48 8d 04 40 lea \(%rax,%rax,2\),%rax + +[a-f0-9]+: c9 leaveq + +[a-f0-9]+: 6e outsb %ds:\(%rsi\),\(%dx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: ac lods %ds:\(%rsi\),%al + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: f3 a5 rep movsl %ds:\(%rsi\),%es:\(%rdi\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: f3 af repz scas %es:\(%rdi\),%eax + +[a-f0-9]+: f3 a7 repz cmpsl %es:\(%rdi\),%ds:\(%rsi\) + +[a-f0-9]+: f3 ad rep lods %ds:\(%rsi\),%eax + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 41 83 03 01 addl \$0x1,\(%r11\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 41 0f ba 23 01 btl \$0x1,\(%r11\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 48 0f c1 03 xadd %rax,\(%rbx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 48 0f c1 c3 xadd %rax,%rbx + +[a-f0-9]+: 48 87 03 xchg %rax,\(%rbx\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 48 93 xchg %rax,%rbx + +[a-f0-9]+: 48 39 45 40 cmp %rax,0x40\(%rbp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 48 3b 45 40 cmp 0x40\(%rbp\),%rax + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 48 01 45 40 add %rax,0x40\(%rbp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 48 03 00 add \(%rax\),%rax + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 48 85 45 40 test %rax,0x40\(%rbp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 48 85 45 40 test %rax,0x40\(%rbp\) + +[a-f0-9]+: 0f ae e8 lfence +#pass diff --git a/gas/testsuite/gas/i386/x86-64-lfence-load.d b/gas/testsuite/gas/i386/x86-64-lfence-load.d index 4f6cd00edf..f21aba85d5 100644 --- a/gas/testsuite/gas/i386/x86-64-lfence-load.d +++ b/gas/testsuite/gas/i386/x86-64-lfence-load.d @@ -1,6 +1,7 @@ -#as: -mlfence-after-load=yes +#as: -mlfence-after-load=all #objdump: -dw -#name: x86-64 -mlfence-after-load=yes +#warning_output: lfence-load.e +#name: x86-64 -mlfence-after-load=all .*: +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 76d0886617..2a3ac6b7d2 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 26e5b48bec..d8e6fa059d 100644 --- a/gas/testsuite/gas/i386/x86-64-lfence-ret-a.d +++ b/gas/testsuite/gas/i386/x86-64-lfence-ret-a.d @@ -1,5 +1,6 @@ -#source: lfence-ret.s +#source: x86-64-lfence-ret.s #as: -mlfence-before-ret=or +#warning_output: x86-64-lfence-ret.e #objdump: -dw #name: x86-64 -mlfence-before-ret=or @@ -9,10 +10,40 @@ Disassembly of section .text: 0+ <_start>: + +[a-f0-9]+: 66 83 0c 24 00 orw \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c3 retw + +[a-f0-9]+: 66 83 0c 24 00 orw \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c2 14 00 retw \$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 340488831d..e9bb64fe94 100644 --- a/gas/testsuite/gas/i386/x86-64-lfence-ret-b.d +++ b/gas/testsuite/gas/i386/x86-64-lfence-ret-b.d @@ -1,5 +1,6 @@ -#source: lfence-ret.s +#source: x86-64-lfence-ret.s #as: -mlfence-before-ret=not +#warning_output: x86-64-lfence-ret.e #objdump: -dw #name: x86-64 -mlfence-before-ret=not @@ -9,6 +10,14 @@ Disassembly of section .text: 0+ <_start>: + +[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 c3 retw + +[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 c2 14 00 retw \$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 0000000000..d5027d385f --- /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 + +.*: +file format .* + + +Disassembly of section .text: + +0+ <_start>: + +[a-f0-9]+: 66 83 0c 24 00 orw \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c3 retw + +[a-f0-9]+: 66 83 0c 24 00 orw \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c2 14 00 retw \$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 0000000000..533445fee6 --- /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 +#name: x86-64 -mlfence-before-ret=shl + +.*: +file format .* + + +Disassembly of section .text: + +0+ <_start>: + +[a-f0-9]+: 66 c1 24 24 00 shlw \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c3 retw + +[a-f0-9]+: 66 c1 24 24 00 shlw \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c2 14 00 retw \$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 0000000000..646b352a62 --- /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 +#name: x86-64 -mlfence-before-ret=yes + +.*: +file format .* + + +Disassembly of section .text: + +0+ <_start>: + +[a-f0-9]+: 66 c1 24 24 00 shlw \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c3 retw + +[a-f0-9]+: 66 c1 24 24 00 shlw \$0x0,\(%rsp\) + +[a-f0-9]+: 0f ae e8 lfence + +[a-f0-9]+: 66 c2 14 00 retw \$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 0000000000..13730e50e6 --- /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 0000000000..986239c222 --- /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 -- 2.18.1 > > + if (lfence_before_ret == lfence_before_ret_not) > > { > > - p = frag_more ((flag_code == CODE_64BIT ? 2 : 0) + 6 + 3); > > - /* notl: 0xf71424. */ > > - if (flag_code == CODE_64BIT) > > - *p++ = 0x48; > > + /* notl: 0xf71424, may add prefix > > + for operand size overwrite or 64-bit code. */ > > Despite the comment extension you still say "notl". Please switch > toi either just "not" or something like "not{w,l,q}". Also > s/overwrite/override/. Note how you ... > > > + 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) > > + { > > + /* orl: 0x830c2400, may add prefix > > + for operand size overwrite or 64-bit code. */ > > ... also have the same (bogus) suffixe here, but ... > > > + *p++ = 0x83; > > + *p++ = 0x0c; > > + } > > + else > > + { > > + /* shl: 0xc1242400, may add prefix > > + for operand size overwrite or 64-bit code. */ > > ... not here. > > Jan -- BR, Hongtao
- Previous message (by thread): [PATCH 1/2] i386: Generate lfence with load/indirect branch/ret [CVE-2020-0551]
- Next message (by thread): [PATCH 1/2] i386: Generate lfence with load/indirect branch/ret [CVE-2020-0551]
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list