Skip to content
Snippets Groups Projects
Forked from Glasgow Haskell Compiler / GHC
Source project has a limited visibility.
  • Matthew Pickering's avatar
    f4da90f1
    interpreter: Fix underflow frame lookups · f4da90f1
    Matthew Pickering authored and Marge Bot's avatar Marge Bot committed
    BCOs can be nested, resulting in nested BCO stack frames where the inner most
    stack frame can refer to variables stored on earlier stack frames via the
    PUSH_L instruction.
    
    |---------|
    |  BCO_1  | -<-┐
    |---------|
     .........     |
    |---------|    | PUSH_L <n>
    |  BCO_N  | ->-┘
    |---------|
    
    Here BCO_N is syntactically nested within the code for BCO_1 and will result
    in code that references the prior stack frame of BCO_1 for some of it's local
    variables. If a stack overflow happens between the creation of the stack frame
    for BCO_1 and BCO_N the RTS might move BCO_N to a new stack chunk while leaving
    BCO_1 in place, invalidating a simple offset based reference to the outer stack
    frames.
    Therefore `ReadSpW` first performs a bounds check to ensure that accesses onto
    the stack will succeed. If the target address would not be a valid location for
    the current stack chunk then `slow_spw` function is called, which dereferences
    the underflow frame to adjust the offset before performing the lookup.
    
                   ┌->--x   |  CHK_1  |
    |  CHK_2  |    |    |   |---------|
    |---------|    |    └-> |  BCO_1  |
    | UD_FLOW | -- x        |---------|
    |---------|    |
    | ......  |    |
    |---------|    | PUSH_L <n>
    |  BCO_ N | ->-┘
    |---------|
    
    Fixes #25750
    f4da90f1
    History
    interpreter: Fix underflow frame lookups
    Matthew Pickering authored and Marge Bot's avatar Marge Bot committed
    BCOs can be nested, resulting in nested BCO stack frames where the inner most
    stack frame can refer to variables stored on earlier stack frames via the
    PUSH_L instruction.
    
    |---------|
    |  BCO_1  | -<-┐
    |---------|
     .........     |
    |---------|    | PUSH_L <n>
    |  BCO_N  | ->-┘
    |---------|
    
    Here BCO_N is syntactically nested within the code for BCO_1 and will result
    in code that references the prior stack frame of BCO_1 for some of it's local
    variables. If a stack overflow happens between the creation of the stack frame
    for BCO_1 and BCO_N the RTS might move BCO_N to a new stack chunk while leaving
    BCO_1 in place, invalidating a simple offset based reference to the outer stack
    frames.
    Therefore `ReadSpW` first performs a bounds check to ensure that accesses onto
    the stack will succeed. If the target address would not be a valid location for
    the current stack chunk then `slow_spw` function is called, which dereferences
    the underflow frame to adjust the offset before performing the lookup.
    
                   ┌->--x   |  CHK_1  |
    |  CHK_2  |    |    |   |---------|
    |---------|    |    └-> |  BCO_1  |
    | UD_FLOW | -- x        |---------|
    |---------|    |
    | ......  |    |
    |---------|    | PUSH_L <n>
    |  BCO_ N | ->-┘
    |---------|
    
    Fixes #25750
Code owners
Assign users and groups as approvers for specific file changes. Learn more.