You need to sign in or sign up before continuing.
  • Ammar Faizi's avatar
    tools/nolibc: i386: Fix a stack misalign bug on _start · d873a364
    Ammar Faizi authored
    The ABI mandates that the %esp register must be a multiple of 16 when
    executing a 'call' instruction.
    
    Commit 2ab44633 ("tools/nolibc: i386: shrink _start with _start_c")
    simplified the _start function, but it didn't take care of the %esp
    alignment, causing SIGSEGV on SSE and AVX programs that use aligned move
    instruction (e.g., movdqa, movaps, and vmovdqa).
    
    The 'and $-16, %esp' aligns the %esp at a multiple of 16. Then 'push
    %eax' will subtract the %esp by 4; thus, it breaks the 16-byte
    alignment. Make sure the %esp is correctly aligned after the push by
    subtracting 12 before the push.
    
    Extra:
    Add 'add $12, %esp' before the 'and $-16, %esp' to avoid over-estimating
    for particular cases as suggested by Willy.
    
    A test program to validate the %esp alignment on _start can be found at:
    
       https://lore.kernel.org/lkml/ZOoindMFj1UKqo+s@biznet-home.integral.gnuweeb.org
    
    [ Thomas: trim Fixes tag commit id ]
    
    Cc: Zhangjin Wu <falcon@tinylab.org>
    Fixes: 2...
    d873a364
arch-i386.h 8.82 KB