2005-01-07 05:02:00

by John Kacur

[permalink] [raw]
Subject: minor nit with decoding popf instruction - was Re: ptrace single-stepping change breaks Wine

On Fri, 2004-12-31 at 17:01, Linus Torvalds wrote:
> On Fri, 31 Dec 2004, Davide Libenzi wrote:
> >
> > I don't think Linus ever posted a POPF-only patch. Try to comment those
> > lines in his POPF patch ...
>
> Here the two patches are independently, if people want to take a look.
>
> If somebody wants to split (and test) the TF-careful thing further (the
> "send_sigtrap()" changes are independent, I think), that would be
> wonderful... Hint hint.
>
> Linus

+static inline int is_at_popf(struct task_struct *child, struct pt_regs
*regs)
+{
+ int i, copied;
+ unsigned char opcode[16];
+ unsigned long addr = convert_eip_to_linear(child, regs);
+
+ copied = access_process_vm(child, addr, opcode, sizeof(opcode),
0);
+ for (i = 0; i < copied; i++) {
+ switch (opcode[i]) {
+ /* popf */
+ case 0x9d:
+ return 1;
+ /* opcode and address size prefixes */
+ case 0x66: case 0x67:
+ continue;
+ /* irrelevant prefixes (segment overrides and repeats)
*/
+ case 0x26: case 0x2e:
+ case 0x36: case 0x3e:
+ case 0x64: case 0x65:
+ case 0xf0: case 0xf2: case 0xf3:
+ continue;
+
+ /*
+ * pushf: NOTE! We should probably not let
+ * the user see the TF bit being set. But
+ * it's more pain than it's worth to avoid
+ * it, and a debugger could emulate this
+ * all in user space if it _really_ cares.
+ */
+ case 0x9c:
+ default:
+ return 0;
+ }
+ }
+ return 0;
+}

In order to avoid false positives, I think you should remove the line
case 0xf0: case 0xf2: case 0xf3:

0xf0 corresponds to the lock prefix which would trigger an invalid
opcode exception with a popf instruction.

0xf2 and 0xf3 correspond to the repeat prefixes and are also not valid
with popf



2005-01-07 06:48:24

by Linus Torvalds

[permalink] [raw]
Subject: Re: minor nit with decoding popf instruction - was Re: ptrace single-stepping change breaks Wine



On Thu, 6 Jan 2005, John Kacur wrote:
>
> In order to avoid false positives, I think you should remove the line
> case 0xf0: case 0xf2: case 0xf3:

False positives are ok with instructions that trap - if it traps, we won't
much care, since the debugger will get notified about that separately (and
unambiguously).

Also:

> 0xf0 corresponds to the lock prefix which would trigger an invalid
> opcode exception with a popf instruction.
>
> 0xf2 and 0xf3 correspond to the repeat prefixes and are also not valid
> with popf

I don't think either of those are necessarily true on older x86 chips.
Nonsensical prefixes used to be silently ignored. Only in later chips has
Intel been more strict about them, and given them meanings.

In fact, I'm pretty sure it's only "lock" that Intel got a lot more
careful about. Try it. I'm pretty sure a "rep" prefix is still accepted
in front of pretty much all instructions. It just doesn't do anything.

Is it used? Probably not. But people have done some strange things to
"mark" instructions (ie for things like run-time exception handling you
can "mark" an instruction by prefixing it with a nonsensical "rep" prefix:
the CPU won't care, and you can check at trap time whether it was one of
your magic instructions.

Of course, I'd never admit to doing anything that obscure. Never.

Linus

2005-01-08 05:16:56

by John Kacur

[permalink] [raw]
Subject: Re: minor nit with decoding popf instruction - was Re: ptrace single-stepping change breaks Wine

On Fri, 2005-01-07 at 01:48, Linus Torvalds wrote:
> On Thu, 6 Jan 2005, John Kacur wrote:
> >
> > In order to avoid false positives, I think you should remove the line
> > case 0xf0: case 0xf2: case 0xf3:
>
> False positives are ok with instructions that trap - if it traps, we won't
> much care, since the debugger will get notified about that separately (and
> unambiguously).
>
True, I never thought of that, however, you still can drop the test,
there's no point continuing if you detected a lock prefix.

> Also:
>
> > 0xf0 corresponds to the lock prefix which would trigger an invalid
> > opcode exception with a popf instruction.
> >
> > 0xf2 and 0xf3 correspond to the repeat prefixes and are also not valid
> > with popf
>
> I don't think either of those are necessarily true on older x86 chips.
> Nonsensical prefixes used to be silently ignored. Only in later chips has
> Intel been more strict about them, and given them meanings.
>
> In fact, I'm pretty sure it's only "lock" that Intel got a lot more
> careful about. Try it. I'm pretty sure a "rep" prefix is still accepted
> in front of pretty much all instructions. It just doesn't do anything.
>
> Is it used? Probably not. But people have done some strange things to
> "mark" instructions (ie for things like run-time exception handling you
> can "mark" an instruction by prefixing it with a nonsensical "rep" prefix:
> the CPU won't care, and you can check at trap time whether it was one of
> your magic instructions.
>
> Of course, I'd never admit to doing anything that obscure. Never.
>
> Linus

You're right, in practice I've never seen a processor trigger an
exception when it encounters a nonsensical rep prefix, so dropping the
tests for 0xf2 and 0xf3 could potentially miss cases in the unlikely
event that a compiler generated them. Not relevant here, but that
strange technique to mark the instructions would backfire on 128-bit and
64-bit media instructions that use 0xf2 and 0xf3 in the encoding.

John