Russ Cox | d98553a | 2014-11-11 17:04:34 -0500 | [diff] [blame] | 1 | // Copyright 2011 The Go Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style |
| 3 | // license that can be found in the LICENSE file. |
| 4 | |
| 5 | package runtime |
| 6 | |
| 7 | /* |
| 8 | Stack layout parameters. |
| 9 | Included both by runtime (compiled via 6c) and linkers (compiled via gcc). |
| 10 | |
| 11 | The per-goroutine g->stackguard is set to point StackGuard bytes |
| 12 | above the bottom of the stack. Each function compares its stack |
| 13 | pointer against g->stackguard to check for overflow. To cut one |
| 14 | instruction from the check sequence for functions with tiny frames, |
| 15 | the stack is allowed to protrude StackSmall bytes below the stack |
| 16 | guard. Functions with large frames don't bother with the check and |
| 17 | always call morestack. The sequences are (for amd64, others are |
| 18 | similar): |
| 19 | |
| 20 | guard = g->stackguard |
| 21 | frame = function's stack frame size |
| 22 | argsize = size of function arguments (call + return) |
| 23 | |
| 24 | stack frame size <= StackSmall: |
| 25 | CMPQ guard, SP |
| 26 | JHI 3(PC) |
| 27 | MOVQ m->morearg, $(argsize << 32) |
| 28 | CALL morestack(SB) |
| 29 | |
| 30 | stack frame size > StackSmall but < StackBig |
| 31 | LEAQ (frame-StackSmall)(SP), R0 |
| 32 | CMPQ guard, R0 |
| 33 | JHI 3(PC) |
| 34 | MOVQ m->morearg, $(argsize << 32) |
| 35 | CALL morestack(SB) |
| 36 | |
| 37 | stack frame size >= StackBig: |
| 38 | MOVQ m->morearg, $((argsize << 32) | frame) |
| 39 | CALL morestack(SB) |
| 40 | |
| 41 | The bottom StackGuard - StackSmall bytes are important: there has |
| 42 | to be enough room to execute functions that refuse to check for |
| 43 | stack overflow, either because they need to be adjacent to the |
| 44 | actual caller's frame (deferproc) or because they handle the imminent |
| 45 | stack overflow (morestack). |
| 46 | |
| 47 | For example, deferproc might call malloc, which does one of the |
| 48 | above checks (without allocating a full frame), which might trigger |
| 49 | a call to morestack. This sequence needs to fit in the bottom |
| 50 | section of the stack. On amd64, morestack's frame is 40 bytes, and |
| 51 | deferproc's frame is 56 bytes. That fits well within the |
| 52 | StackGuard - StackSmall bytes at the bottom. |
| 53 | The linkers explore all possible call traces involving non-splitting |
| 54 | functions to make sure that this limit cannot be violated. |
| 55 | */ |
| 56 | |
| 57 | const ( |
| 58 | // StackSystem is a number of additional bytes to add |
| 59 | // to each stack below the usual guard area for OS-specific |
Shenghou Ma | 56e8f8e | 2014-12-26 01:07:10 -0500 | [diff] [blame] | 60 | // purposes like signal handling. Used on Windows, Plan 9, |
| 61 | // and Darwin/ARM because they do not use a separate stack. |
| 62 | _StackSystem = goos_windows*512*ptrSize + goos_plan9*512 + goos_darwin*goarch_arm*1024 |
Russ Cox | d98553a | 2014-11-11 17:04:34 -0500 | [diff] [blame] | 63 | |
| 64 | // The minimum size of stack used by Go code |
| 65 | _StackMin = 2048 |
| 66 | |
| 67 | // The minimum stack size to allocate. |
| 68 | // The hackery here rounds FixedStack0 up to a power of 2. |
| 69 | _FixedStack0 = _StackMin + _StackSystem |
| 70 | _FixedStack1 = _FixedStack0 - 1 |
| 71 | _FixedStack2 = _FixedStack1 | (_FixedStack1 >> 1) |
| 72 | _FixedStack3 = _FixedStack2 | (_FixedStack2 >> 2) |
| 73 | _FixedStack4 = _FixedStack3 | (_FixedStack3 >> 4) |
| 74 | _FixedStack5 = _FixedStack4 | (_FixedStack4 >> 8) |
| 75 | _FixedStack6 = _FixedStack5 | (_FixedStack5 >> 16) |
| 76 | _FixedStack = _FixedStack6 + 1 |
| 77 | |
| 78 | // Functions that need frames bigger than this use an extra |
| 79 | // instruction to do the stack split check, to avoid overflow |
| 80 | // in case SP - framesize wraps below zero. |
| 81 | // This value can be no bigger than the size of the unmapped |
| 82 | // space at zero. |
| 83 | _StackBig = 4096 |
| 84 | |
| 85 | // The stack guard is a pointer this many bytes above the |
| 86 | // bottom of the stack. |
Russ Cox | db40624 | 2014-12-05 19:50:09 -0500 | [diff] [blame] | 87 | _StackGuard = 640 + _StackSystem |
Russ Cox | d98553a | 2014-11-11 17:04:34 -0500 | [diff] [blame] | 88 | |
| 89 | // After a stack split check the SP is allowed to be this |
| 90 | // many bytes below the stack guard. This saves an instruction |
| 91 | // in the checking sequence for tiny frames. |
| 92 | _StackSmall = 128 |
| 93 | |
| 94 | // The maximum number of bytes that a chain of NOSPLIT |
| 95 | // functions can use. |
| 96 | _StackLimit = _StackGuard - _StackSystem - _StackSmall |
| 97 | ) |
| 98 | |
| 99 | // Goroutine preemption request. |
Russ Cox | e6d3511 | 2015-01-05 16:29:21 +0000 | [diff] [blame] | 100 | // Stored into g->stackguard0 to cause split stack check failure. |
Russ Cox | d98553a | 2014-11-11 17:04:34 -0500 | [diff] [blame] | 101 | // Must be greater than any real sp. |
| 102 | // 0xfffffade in hex. |
| 103 | const ( |
| 104 | _StackPreempt = uintptrMask & -1314 |
| 105 | _StackFork = uintptrMask & -1234 |
| 106 | ) |