mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
[release-branch.go1.4] runtime: mark stacks with MAP_STACK on openbsd
OpenBSD 6.4+ requires that stack regions be marked with MAP_STACK. MAP_STACK is permitted (but is a no-op) on OpenBSD 6.3. Change-Id: I8118f27e6a0feb97ae570cbc8aad461ec20676fa Reviewed-on: https://go-review.googlesource.com/c/154477 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
182bdbb1e1
commit
bdd4b9503e
@ -14,6 +14,7 @@ enum {
|
|||||||
MAP_ANON = 0x1000,
|
MAP_ANON = 0x1000,
|
||||||
MAP_PRIVATE = 0x2,
|
MAP_PRIVATE = 0x2,
|
||||||
MAP_FIXED = 0x10,
|
MAP_FIXED = 0x10,
|
||||||
|
MAP_STACK = 0x4000,
|
||||||
|
|
||||||
MADV_FREE = 0x6,
|
MADV_FREE = 0x6,
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ enum {
|
|||||||
MAP_ANON = 0x1000,
|
MAP_ANON = 0x1000,
|
||||||
MAP_PRIVATE = 0x2,
|
MAP_PRIVATE = 0x2,
|
||||||
MAP_FIXED = 0x10,
|
MAP_FIXED = 0x10,
|
||||||
|
MAP_STACK = 0x4000,
|
||||||
|
|
||||||
MADV_FREE = 0x6,
|
MADV_FREE = 0x6,
|
||||||
|
|
||||||
|
@ -197,6 +197,8 @@ struct MLink
|
|||||||
// if accessed. Used only for debugging the runtime.
|
// if accessed. Used only for debugging the runtime.
|
||||||
|
|
||||||
void* runtime·sysAlloc(uintptr nbytes, uint64 *stat);
|
void* runtime·sysAlloc(uintptr nbytes, uint64 *stat);
|
||||||
|
void runtime·sysMarkStack(void *v, uintptr nbytes);
|
||||||
|
void runtime·sysUnmarkStack(void *v, uintptr nbytes);
|
||||||
void runtime·SysFree(void *v, uintptr nbytes, uint64 *stat);
|
void runtime·SysFree(void *v, uintptr nbytes, uint64 *stat);
|
||||||
void runtime·SysUnused(void *v, uintptr nbytes);
|
void runtime·SysUnused(void *v, uintptr nbytes);
|
||||||
void runtime·SysUsed(void *v, uintptr nbytes);
|
void runtime·SysUsed(void *v, uintptr nbytes);
|
||||||
|
@ -27,6 +27,29 @@ runtime·sysAlloc(uintptr n, uint64 *stat)
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma textflag NOSPLIT
|
||||||
|
void
|
||||||
|
runtime·sysMarkStack(void *v, uintptr n)
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
// Stack regions on OpenBSD 6.4+ must be marked with MAP_STACK.
|
||||||
|
p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE|MAP_FIXED|MAP_STACK, -1, 0);
|
||||||
|
if (p == ((void *)-1) || p != v)
|
||||||
|
runtime·throw("runtime: failed to mark stack");
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma textflag NOSPLIT
|
||||||
|
void
|
||||||
|
runtime·sysUnmarkStack(void *v, uintptr n)
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
|
||||||
|
if (p == ((void *)-1) || p != v)
|
||||||
|
runtime·throw("runtime: failed to unmark stack");
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
runtime·SysUnused(void *v, uintptr n)
|
runtime·SysUnused(void *v, uintptr n)
|
||||||
{
|
{
|
||||||
|
@ -167,7 +167,10 @@ runtime·newosproc(M *mp, void *stk)
|
|||||||
|
|
||||||
param.tf_tcb = (byte*)&mp->tls[0];
|
param.tf_tcb = (byte*)&mp->tls[0];
|
||||||
param.tf_tid = (int32*)&mp->procid;
|
param.tf_tid = (int32*)&mp->procid;
|
||||||
param.tf_stack = stk;
|
|
||||||
|
// Stack pointer must point inside stack area (as marked with MAP_STACK),
|
||||||
|
// rather than at the top of it.
|
||||||
|
param.tf_stack = (void*)((uintptr)stk - sizeof(uintptr));
|
||||||
|
|
||||||
oset = runtime·sigprocmask(SIG_SETMASK, sigset_all);
|
oset = runtime·sigprocmask(SIG_SETMASK, sigset_all);
|
||||||
ret = runtime·tfork(¶m, sizeof(param), mp, mp->g0, runtime·mstart);
|
ret = runtime·tfork(¶m, sizeof(param), mp, mp->g0, runtime·mstart);
|
||||||
|
@ -71,6 +71,9 @@ poolalloc(uint8 order)
|
|||||||
runtime·throw("bad ref");
|
runtime·throw("bad ref");
|
||||||
if(s->freelist != nil)
|
if(s->freelist != nil)
|
||||||
runtime·throw("bad freelist");
|
runtime·throw("bad freelist");
|
||||||
|
#ifdef GOOS_openbsd
|
||||||
|
runtime·sysMarkStack((void *)(s->start << PageShift), s->npages << PageShift);
|
||||||
|
#endif
|
||||||
for(i = 0; i < StackCacheSize; i += FixedStack << order) {
|
for(i = 0; i < StackCacheSize; i += FixedStack << order) {
|
||||||
x = (MLink*)((s->start << PageShift) + i);
|
x = (MLink*)((s->start << PageShift) + i);
|
||||||
x->next = s->freelist;
|
x->next = s->freelist;
|
||||||
@ -110,6 +113,9 @@ poolfree(MLink *x, uint8 order)
|
|||||||
// span is completely free - return to heap
|
// span is completely free - return to heap
|
||||||
runtime·MSpanList_Remove(s);
|
runtime·MSpanList_Remove(s);
|
||||||
s->freelist = nil;
|
s->freelist = nil;
|
||||||
|
#ifdef GOOS_openbsd
|
||||||
|
runtime·sysUnmarkStack((void *)(s->start << PageShift), s->npages << PageShift);
|
||||||
|
#endif
|
||||||
runtime·MHeap_FreeStack(&runtime·mheap, s);
|
runtime·MHeap_FreeStack(&runtime·mheap, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -246,6 +252,9 @@ runtime·stackalloc(uint32 n)
|
|||||||
s = runtime·MHeap_AllocStack(&runtime·mheap, ROUND(n, PageSize) >> PageShift);
|
s = runtime·MHeap_AllocStack(&runtime·mheap, ROUND(n, PageSize) >> PageShift);
|
||||||
if(s == nil)
|
if(s == nil)
|
||||||
runtime·throw("out of memory");
|
runtime·throw("out of memory");
|
||||||
|
#ifdef GOOS_openbsd
|
||||||
|
runtime·sysMarkStack((void *)(s->start << PageShift), s->npages << PageShift);
|
||||||
|
#endif
|
||||||
v = (byte*)(s->start<<PageShift);
|
v = (byte*)(s->start<<PageShift);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,6 +316,9 @@ runtime·stackfree(Stack stk)
|
|||||||
runtime·printf("%p %p\n", s->start<<PageShift, v);
|
runtime·printf("%p %p\n", s->start<<PageShift, v);
|
||||||
runtime·throw("bad span state");
|
runtime·throw("bad span state");
|
||||||
}
|
}
|
||||||
|
#ifdef GOOS_openbsd
|
||||||
|
runtime·sysUnmarkStack((void *)(s->start << PageShift), s->npages << PageShift);
|
||||||
|
#endif
|
||||||
runtime·MHeap_FreeStack(&runtime·mheap, s);
|
runtime·MHeap_FreeStack(&runtime·mheap, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user