• R
    fix regression in i386 inline syscall asm producing invalid code · c8798ef9
    Rich Felker 提交于
    commit 22e5bbd0 inlined the i386
    syscall mechanism, but wrongly assumed memory operands to the 5- and
    6-argument syscall asm would be esp-based. however, nothing in the
    constraints prevented them from being ebx- or ebp-based, and in those
    cases, ebx and ebp could be clobbered before use of the memory operand
    was complete. in the 6-argument case, this prevented restoration of
    the original register values before the end of the asm block, breaking
    the asm contract since ebx and ebp are not marked as clobbered. (they
    can't be, because lots of compilers don't accept these registers in
    constraints or clobbers if PIC or frame pointer is enabled).
    
    doing this right is complicated by the fact that, after a single push,
    no operands which might be memory operands are usable. if they are
    esp-based, the value of esp has changed, rendering them invalid.
    
    introduce some new dances to load the registers. for the 5-arg case,
    push the operand that may be a memory operand first, and after that,
    it doesn't matter if the operand is invalid, since we'll just use the
    newly pushed value. for the 6-arg case, we need to put both operands
    in memory to begin with, like the old non-inline code prior to commit
    22e5bbd0 accepted, so that there's
    only one potentially memory-based operand to the asm. this can then be
    saved with a single push, and after that the values can be read off
    into the registers they're needed in.
    
    there's some size overhead, but still a lot less execution overhead
    than the old out-of-line code. doing it better depends on a modern
    compiler that lets you use ebx and ebp in asm constraints without
    restriction. the failure modes on compilers where this doesn't work
    are inconsistent and dangerous (on at least some gcc versions 4.x and
    earlier, wrong codegen!), so this is a delicate matter. it can be
    addressed later if needed.
    c8798ef9
syscall_arch.h 2.2 KB