Skip to content

Remove segmented stack prelude on Windows #14742

Closed
@klutzy

Description

@klutzy

On Windows, stack overflow is detected via two ways:

  1. Threads have guard page at the end of stack, so it will cause segmentation fault if you try to access guard page.
    (To be precise, guard page is set at uncommitted page therefore it detects when to commit page or fail if stack is full).
    Green threads also have guard page via VirtualProtect.
  2. Guard page is insufficient if a function consumes stack more than page size, thus "jumps" over guard page. To prevent this, Windows compilers add __chkstk() or _alloca() if frame size is greater than 4096. The checker functions tries to access all pages between base pointer and stack pointer.

LLVM also has such support. This is already happening:

$ cat a.rs
#![no_std]
#![crate_type = "lib"]
pub fn large() {
    let a = [0u8, ..4096];
}

$ rustc a.rs --target=i686-pc-mingw32 --emit=asm -o a.win.s
__ZN5large20h4dd5255028807332baa4v0.0E::
    .cfi_startproc
    leal    -4104(%esp), %ecx
    cmpl    %fs:20, %ecx
    ja  LBB0_0
    pushl   $0
    pushl   $4104
    calll   ___morestack
    retl
LBB0_0:
    movl    $4104, %eax
    calll   __alloca
...

So we can completely remove __morestack here and use _alloca for detection.

Also, currently LLVM uses %fs:0x14 for segmetend stack support, but it seems to break a lot of things: See #13259 and its related issues.

cc #11871

Metadata

Metadata

Assignees

No one assigned

    Labels

    O-windowsOperating system: Windows

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions