lkml.org 
[lkml]   [2008]   [Apr]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH 1/1] x86: fix text_poke
    * H. Peter Anvin (hpa@zytor.com) wrote:
    > Mathieu Desnoyers wrote:
    >>>> b) there might be a jump into the middle of this instruction sequence?
    >>>>
    >>> If we change that, as discussed above, so the liveliness of ZF and of
    >>> the %al register is still insured by leaving the mov and test
    >>> instructions in place, we end up only modifying a single instruction and
    >>> the problem fades away. We would end up changing a jne for a jmp.
    >> So, if we do is I propose here, we have to take into account this
    >> question too. Any jump that jumps in the middle of this instruction
    >> sequence would have to insure correct liveliness of %al and ZF. However,
    >> since we just limited the scope of their liveliness, there are no other
    >> code paths which can jump in the middle of our instruction sequence and
    >> insure correct ZF and %al liveliness.
    >
    > I wanted to point out that this, in particular, is utter nonsense. Consider
    > a sequence that looks something like this:
    >
    > if (foo ? bar : imv_cond(var)) {
    > blah();
    > }
    >
    > An entirely sane transformation of this (as far as gcc is concerned), is
    > something like:
    >
    > cmpl $0,foo
    > je 1f
    > cmpl $0,bar
    > jmp 2f
    > 1:
    > #APP
    > movb var,%al /* This is your imv */
    > #NO_APP
    > testb %al,%al
    > 2:
    > je 3f
    > call blah
    > 3:
    >
    > Your code would take the movb-testb-je sequence and combine them, then we
    > jump into the middle of the new instruction when jumping at 2!
    >

    I am glad you come up with a counter argument. Let's look at what would
    happen here with my modified code :

    cmpl $0,foo
    je 1f
    cmpl $0,bar
    jmp 2f
    1:
    #APP
    mov %esi, %esi /* nop 2 bytes */
    #NO_APP
    mov %esi, %esi /* nop 2 bytes */
    2:
    jmp 3f /* 2 bytes short jump */
    call blah
    3:

    First of all, I do not "combine" the instructions.. that would be really
    dangerous (and bug-prone, since any interrupt could iret to an invalid
    instruction). No, all I do is to swap instructions for other
    instructions of the same size (or smaller in the case of jne 6 bytes ->
    nop1 + jmp 5 bytes).

    I see the problem you show here : it's dangerous to change an
    instruction generated by gcc because it can be re-used for other
    purposes, as in your example.

    Then, what I propose is the following : instead of modifying the
    conditional branch instruction, I prefix my inline assembly with a 5
    bytes jump. I can then have the exact same behavior as the original
    conditional branch; I either jump at the address following the
    conditional branch or at the target address. I would still have to check
    for ZF and %al liveliness as I proposed earlier, because I would skip
    the movb and test instructions.

    > There are only two ways to deal with this - extensive analysis of the
    > entire flow of control, or telling the compiler exactly what is *actually*
    > going on. The latter is the preferred way, obviously.
    >

    Yes, in an ideal world, gcc would help here.

    Mathieu

    > -hpa
    >

    --
    Mathieu Desnoyers
    Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
    OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68


    \
     
     \ /
      Last update: 2008-04-25 22:07    [W:4.058 / U:0.124 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site