Commit 10d12202 authored by Dominik Charousset's avatar Dominik Charousset

boost.context

parent f15de325
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CTX_ALL_H
#define BOOST_CTX_ALL_H
#include <boost/context/fcontext.hpp>
#include <boost/context/stack_allocator.hpp>
#include <boost/context/stack_utils.hpp>
#endif // BOOST_CTX_ALL_H
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CTX_DETAIL_FCONTEXT_ARM_H
#define BOOST_CTX_DETAIL_FCONTEXT_ARM_H
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/context/detail/config.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace ctx {
extern "C" {
#define BOOST_CONTEXT_CALLDECL
struct stack_t
{
void * base;
void * limit;
stack_t() :
base( 0), limit( 0)
{}
};
struct fp_t
{
boost::uint32_t fc_freg[16];
fp_t() :
fc_freg()
{}
};
struct fcontext_t
{
boost::uint32_t fc_greg[11];
stack_t fc_stack;
fp_t fc_fp;
fcontext_t() :
fc_greg(),
fc_stack(),
fc_fp()
{}
};
}
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_CTX_DETAIL_FCONTEXT_ARM_H
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CTX_DETAIL_FCONTEXT_I386H
#define BOOST_CTX_DETAIL_FCONTEXT_I386H
#include <cstddef>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/context/detail/config.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace ctx {
extern "C" {
#define BOOST_CONTEXT_CALLDECL __attribute__((cdecl))
struct stack_t
{
void * base;
void * limit;
stack_t() :
base( 0), limit( 0)
{}
};
struct fp_t
{
boost::uint32_t fc_freg[2];
fp_t() :
fc_freg()
{}
};
struct fcontext_t
{
boost::uint32_t fc_greg[6];
stack_t fc_stack;
fp_t fc_fp;
fcontext_t() :
fc_greg(),
fc_stack(),
fc_fp()
{}
};
}
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_CTX_DETAIL_FCONTEXT_I386_H
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CTX_DETAIL_FCONTEXT_I386H
#define BOOST_CTX_DETAIL_FCONTEXT_I386H
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/context/detail/config.hpp>
#pragma warning(push)
#pragma warning(disable:4351)
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace ctx {
extern "C" {
#define BOOST_CONTEXT_CALLDECL __cdecl
struct stack_t
{
void * base;
void * limit;
stack_t() :
base( 0), limit( 0)
{}
};
struct fp_t
{
boost::uint32_t fc_freg[2];
fp_t() :
fc_freg()
{}
};
struct fcontext_t
{
boost::uint32_t fc_greg[6];
stack_t fc_stack;
void * fc_excpt_lst;
void * fc_local_storage;
fp_t fc_fp;
fcontext_t() :
fc_greg(),
fc_stack(),
fc_excpt_lst( 0),
fc_local_storage( 0),
fc_fp()
{}
};
}
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#pragma warning(pop)
#endif // BOOST_CTX_DETAIL_FCONTEXT_I386_H
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CTX_DETAIL_FCONTEXT_MIPS_H
#define BOOST_CTX_DETAIL_FCONTEXT_MIPS_H
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/context/detail/config.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace ctx {
extern "C" {
#define BOOST_CONTEXT_CALLDECL
// on MIPS we assume 64bit regsiters - even for 32bit ABIs
struct stack_t
{
void * base;
void * limit;
stack_t() :
base( 0), limit( 0)
{}
};
struct fp_t
{
boost::uint64_t fc_freg[6];
fp_t() :
fc_freg()
{}
};
struct fcontext_t
{
boost::uint64_t fc_greg[13];
stack_t fc_stack;
fp_t fc_fp;
fcontext_t() :
fc_greg(),
fc_stack(),
fc_fp()
{}
};
}
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_CTX_DETAIL_FCONTEXT_MIPS_H
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CTX_DETAIL_FCONTEXT_PPC_H
#define BOOST_CTX_DETAIL_FCONTEXT_PPC_H
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/context/detail/config.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace ctx {
extern "C" {
#define BOOST_CONTEXT_CALLDECL
struct stack_t
{
void * base;
void * limit;
stack_t() :
base( 0), limit( 0)
{}
};
struct fp_t
{
boost::uint64_t fc_freg[19];
fp_t() :
fc_freg()
{}
};
struct fcontext_t
{
# if defined(__powerpc64__)
boost::uint64_t fc_greg[23];
# else
boost::uint32_t fc_greg[23];
# endif
stack_t fc_stack;
fp_t fc_fp;
fcontext_t() :
fc_greg(),
fc_stack(),
fc_fp()
{}
};
}
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_CTX_DETAIL_FCONTEXT_PPC_H
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CTX_DETAIL_FCONTEXT_X86_64_H
#define BOOST_CTX_DETAIL_FCONTEXT_X86_64_H
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/context/detail/config.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace ctx {
extern "C" {
#define BOOST_CONTEXT_CALLDECL
struct stack_t
{
void * base;
void * limit;
stack_t() :
base( 0), limit( 0)
{}
};
struct fp_t
{
boost::uint32_t fc_freg[2];
fp_t() :
fc_freg()
{}
};
struct fcontext_t
{
boost::uint64_t fc_greg[8];
stack_t fc_stack;
fp_t fc_fp;
fcontext_t() :
fc_greg(),
fc_stack(),
fc_fp()
{}
};
}
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_CTX_DETAIL_FCONTEXT_X86_64_H
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CTX_DETAIL_FCONTEXT_X86_64_H
#define BOOST_CTX_DETAIL_FCONTEXT_X86_64_H
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/context/detail/config.hpp>
#pragma warning(push)
#pragma warning(disable:4351)
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace ctx {
extern "C" {
#define BOOST_CONTEXT_CALLDECL
struct stack_t
{
void * base;
void * limit;
stack_t() :
base( 0), limit( 0)
{}
};
struct fp_t
{
boost::uint32_t fc_freg[2];
void * fc_xmm;
char fc_buffer[175];
fp_t() :
fc_freg(),
fc_xmm( 0),
fc_buffer()
{
fc_xmm = fc_buffer;
if ( 0 != ( ( ( uintptr_t) fc_xmm) & 15) )
fc_xmm = ( char *) ( ( ( ( uintptr_t) fc_xmm) + 15) & ~0x0F);
}
};
struct fcontext_t
{
boost::uint64_t fc_greg[10];
stack_t fc_stack;
void * fc_local_storage;
fp_t fc_fp;
fcontext_t() :
fc_greg(),
fc_stack(),
fc_local_storage( 0),
fc_fp()
{}
};
}
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#pragma warning(pop)
#endif // BOOST_CTX_DETAIL_FCONTEXT_X86_64_H
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CTX_FCONTEXT_H
#define BOOST_CTX_FCONTEXT_H
#if defined(__PGI)
#include <stdint.h>
#endif
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/context/detail/config.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
// x86_64
// test x86_64 before i386 because icc might
// define __i686__ for x86_64 too
#if defined(__x86_64__) || defined(__x86_64) \
|| defined(__amd64__) || defined(__amd64) \
|| defined(_M_X64) || defined(_M_AMD64)
# if defined(BOOST_WINDOWS)
# include <boost/context/detail/fcontext_x86_64_win.hpp>
# else
# include <boost/context/detail/fcontext_x86_64.hpp>
# endif
// i386
#elif defined(i386) || defined(__i386__) || defined(__i386) \
|| defined(__i486__) || defined(__i586__) || defined(__i686__) \
|| defined(__X86__) || defined(_X86_) || defined(__THW_INTEL__) \
|| defined(__I86__) || defined(__INTEL__) || defined(__IA32__) \
|| defined(_M_IX86) || defined(_I86_)
# if defined(BOOST_WINDOWS)
# include <boost/context/detail/fcontext_i386_win.hpp>
# else
# include <boost/context/detail/fcontext_i386.hpp>
# endif
// arm
#elif defined(__arm__) || defined(__thumb__) || defined(__TARGET_ARCH_ARM) \
|| defined(__TARGET_ARCH_THUMB) || defined(_ARM)
# include <boost/context/detail/fcontext_arm.hpp>
// mips
#elif (defined(__mips) && __mips == 1) || defined(_MIPS_ISA_MIPS1) \
|| defined(_R3000)
# include <boost/context/detail/fcontext_mips.hpp>
// powerpc
#elif defined(__powerpc) || defined(__powerpc__) || defined(__ppc) \
|| defined(__ppc__) || defined(_ARCH_PPC) || defined(__POWERPC__) \
|| defined(__PPCGECKO__) || defined(__PPCBROADWAY) || defined(_XENON)
# include <boost/context/detail/fcontext_ppc.hpp>
#else
# error "platform not supported"
#endif
namespace boost {
namespace ctx {
namespace detail {
extern "C" BOOST_CONTEXT_DECL void * BOOST_CONTEXT_CALLDECL align_stack( void * vp);
}
extern "C" BOOST_CONTEXT_DECL
intptr_t BOOST_CONTEXT_CALLDECL jump_fcontext( fcontext_t * ofc, fcontext_t const* nfc, intptr_t vp, bool preserve_fpu = true);
extern "C" BOOST_CONTEXT_DECL
void BOOST_CONTEXT_CALLDECL make_fcontext( fcontext_t * fc, void (* fn)( intptr_t) );
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_CTX_FCONTEXT_H
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CTX_STACK_ALLOCATOR_H
#define BOOST_CTX_STACK_ALLOCATOR_H
#include <cstddef>
#include <boost/config.hpp>
#include <boost/context/detail/config.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace ctx {
class BOOST_CONTEXT_DECL stack_allocator
{
public:
void * allocate( std::size_t) const;
void deallocate( void *, std::size_t) const;
};
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_CTX_STACK_ALLOCATOR_H
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_CTX_STACK_UTILS_H
#define BOOST_CTX_STACK_UTILS_H
#include <cstddef>
#include <boost/config.hpp>
#include <boost/context/detail/config.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace ctx {
BOOST_CONTEXT_DECL std::size_t default_stacksize();
BOOST_CONTEXT_DECL std::size_t minimum_stacksize();
BOOST_CONTEXT_DECL std::size_t maximum_stacksize();
BOOST_CONTEXT_DECL std::size_t pagesize();
BOOST_CONTEXT_DECL std::size_t page_count( std::size_t stacksize);
BOOST_CONTEXT_DECL bool is_stack_unbound();
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_CTX_STACK_UTILS_H
; Copyright Oliver Kowalke 2009.
; Distributed under the Boost Software License, Version 1.0.
; (See accompanying file LICENSE_1_0.txt or copy at
; http://www.boost.org/LICENSE_1_0.txt)
; --------------------------------------------------------------
; | 0 | 1 | 2 | 3 | 4 | 5 |
; --------------------------------------------------------------
; | 0h | 04h | 08h | 0ch | 010h | 014h |
; --------------------------------------------------------------
; | EDI | ESI | EBX | EBP | ESP | EIP |
; --------------------------------------------------------------
; --------------------------------------------------------------
; | 6 | 7 | |
; --------------------------------------------------------------
; | 018h | 01ch | |
; --------------------------------------------------------------
; | ss_base | ss_limit| |
; --------------------------------------------------------------
; --------------------------------------------------------------
; | 8 | |
; --------------------------------------------------------------
; | 020h | |
; --------------------------------------------------------------
; |fc_execpt| |
; --------------------------------------------------------------
; --------------------------------------------------------------
; | 9 | |
; --------------------------------------------------------------
; | 024h | |
; --------------------------------------------------------------
; |fc_strage| |
; --------------------------------------------------------------
; --------------------------------------------------------------
; | 10 | 11 | |
; --------------------------------------------------------------
; | 028h | 02ch | |
; --------------------------------------------------------------
; | fc_mxcsr|fc_x87_cw| |
; --------------------------------------------------------------
.386
.XMM
.model flat, c
_exit PROTO, value:SDWORD
align_stack PROTO, vp:DWORD
seh_fcontext PROTO, except:DWORD, frame:DWORD, context:DWORD, dispatch:DWORD
.code
jump_fcontext PROC EXPORT
mov ecx, [esp+04h] ; load address of the first fcontext_t arg
mov [ecx], edi ; save EDI
mov [ecx+04h], esi ; save ESI
mov [ecx+08h], ebx ; save EBX
mov [ecx+0ch], ebp ; save EBP
assume fs:nothing
mov edx, fs:[018h] ; load NT_TIB
assume fs:error
mov eax, [edx] ; load current SEH exception list
mov [ecx+020h], eax ; save current exception list
mov eax, [edx+04h] ; load current stack base
mov [ecx+018h], eax ; save current stack base
mov eax, [edx+08h] ; load current stack limit
mov [ecx+01ch], eax ; save current stack limit
mov eax, [edx+010h] ; load fiber local storage
mov [ecx+024h], eax ; save fiber local storage
lea eax, [esp+04h] ; exclude the return address
mov [ecx+010h], eax ; save as stack pointer
mov eax, [esp] ; load return address
mov [ecx+014h], eax ; save return address
mov edx, [esp+08h] ; load address of the second fcontext_t arg
mov edi, [edx] ; restore EDI
mov esi, [edx+04h] ; restore ESI
mov ebx, [edx+08h] ; restore EBX
mov ebp, [edx+0ch] ; restore EBP
mov eax, [esp+010h] ; check if fpu enve preserving was requested
test eax, eax
je nxt
stmxcsr [ecx+028h] ; save MMX control word
fnstcw [ecx+02ch] ; save x87 control word
ldmxcsr [edx+028h] ; restore MMX control word
fldcw [edx+02ch] ; restore x87 control word
nxt:
mov ecx, edx
assume fs:nothing
mov edx, fs:[018h] ; load NT_TIB
assume fs:error
mov eax, [ecx+020h] ; load SEH exception list
mov [edx], eax ; restore next SEH item
mov eax, [ecx+018h] ; load stack base
mov [edx+04h], eax ; restore stack base
mov eax, [ecx+01ch] ; load stack limit
mov [edx+08h], eax ; restore stack limit
mov eax, [ecx+024h] ; load fiber local storage
mov [edx+010h], eax ; restore fiber local storage
mov eax, [esp+0ch] ; use third arg as return value after jump
mov esp, [ecx+010h] ; restore ESP
mov [esp+04h], eax ; use third arg as first arg in context function
mov ecx, [ecx+014h] ; fetch the address to return to
jmp ecx ; indirect jump to context
jump_fcontext ENDP
make_fcontext PROC EXPORT
mov eax, [esp+04h] ; load address of the fcontext_t arg0
mov [eax], eax ; save the address of passed context
mov ecx, [esp+08h] ; load the address of the context function
mov [eax+014h], ecx ; save the address of the context function
mov edx, [eax+018h] ; load the stack base
push eax ; save pointer to fcontext_t
push edx ; stack pointer as arg for align_stack
call align_stack ; align stack
mov edx, eax ; begin of aligned stack
pop eax ; remove arg for align_stack
pop eax ; restore pointer to fcontext_t
lea edx, [edx-014h] ; reserve space for last frame on stack, (ESP + 4) & 15 == 0
mov [eax+010h], edx ; save the aligned stack
mov ecx, seh_fcontext ; set ECX to exception-handler
mov [edx+0ch], ecx ; save ECX as SEH handler
mov ecx, 0ffffffffh ; set ECX to -1
mov [edx+08h], ecx ; save ECX as next SEH item
lea ecx, [edx+08h] ; load address of next SEH item
mov [eax+02ch], ecx ; save next SEH
stmxcsr [eax+028h] ; save MMX control word
fnstcw [eax+02ch] ; save x87 control word
mov ecx, finish ; address of finish
mov [edx], ecx
xor eax, eax
ret
finish:
xor eax, eax
push eax ; exit code is zero
call _exit ; exit application
hlt
make_fcontext ENDP
END
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_CONTEXT_SOURCE
#include <boost/context/fcontext.hpp>
#include <cstddef>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace ctx {
namespace detail {
extern "C" BOOST_CONTEXT_DECL
void * BOOST_CONTEXT_CALLDECL align_stack( void * vp)
{
void * base = vp;
if ( 0 != ( ( ( uintptr_t) base) & 15) )
base = ( char * ) ( ( ( ( uintptr_t) base) - 15) & ~0x0F);
return base;
}
}
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_CONTEXT_SOURCE
extern "C" {
#include <stddef.h>
#include <stdio.h>
#include <excpt.h>
#include <windows.h>
#include <winnt.h>
#if defined(_MSC_VER)
# define SNPRINTF _snprintf
#else
# define SNPRINTF snprintf
#endif
static char * exception_description(
_EXCEPTION_RECORD const* record, char * description, size_t len)
{
const DWORD code = record->ExceptionCode;
const ULONG_PTR * info = record->ExceptionInformation;
switch ( code)
{
case EXCEPTION_ACCESS_VIOLATION:
{
const char * accessType = ( info[0]) ? "writing" : "reading";
const ULONG_PTR address = info[1];
SNPRINTF( description, len, "Access violation %s 0x%08lX", accessType, address);
return description;
}
case EXCEPTION_DATATYPE_MISALIGNMENT: return "Datatype misalignment";
case EXCEPTION_BREAKPOINT: return "Breakpoint";
case EXCEPTION_SINGLE_STEP: return "Single step";
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: return "Array bounds exceeded";
case EXCEPTION_FLT_DENORMAL_OPERAND: return "FPU denormal operand";
case EXCEPTION_FLT_DIVIDE_BY_ZERO: return "FPU divide by zero";
case EXCEPTION_FLT_INEXACT_RESULT: return "FPU inexact result";
case EXCEPTION_FLT_INVALID_OPERATION: return "FPU invalid operation";
case EXCEPTION_FLT_OVERFLOW: return "FPU overflow";
case EXCEPTION_FLT_STACK_CHECK: return "FPU stack check";
case EXCEPTION_FLT_UNDERFLOW: return "FPU underflow";
case EXCEPTION_INT_DIVIDE_BY_ZERO: return "Integer divide by zero";
case EXCEPTION_INT_OVERFLOW: return "Integer overflow";
case EXCEPTION_PRIV_INSTRUCTION: return "Privileged instruction";
case EXCEPTION_IN_PAGE_ERROR: return "In page error";
case EXCEPTION_ILLEGAL_INSTRUCTION: return "Illegal instruction";
case EXCEPTION_NONCONTINUABLE_EXCEPTION: return "Noncontinuable exception";
case EXCEPTION_STACK_OVERFLOW: return "Stack overflow";
case EXCEPTION_INVALID_DISPOSITION: return "Invalid disposition";
case EXCEPTION_GUARD_PAGE: return "Guard page";
case EXCEPTION_INVALID_HANDLE: return "Invalid handle";
}
SNPRINTF( description, len, "Unknown (0x%08lX)", code);
return description;
}
EXCEPTION_DISPOSITION seh_fcontext(
struct _EXCEPTION_RECORD * record,
void *,
struct _CONTEXT *,
void *)
{
char description[255];
fprintf( stderr, "exception: %s (%08lX)\n",
exception_description( record, description, sizeof( description) ),
record->ExceptionCode);
ExitProcess( -1);
return ExceptionContinueSearch; // never reached
}
}
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_CONTEXT_SOURCE
#include <boost/context/stack_allocator.hpp>
extern "C" {
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
}
#include <stdexcept>
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/format.hpp>
#include <boost/context/stack_utils.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace ctx {
void *
stack_allocator::allocate( std::size_t size) const
{
if ( minimum_stacksize() > size)
throw std::invalid_argument(
boost::str( boost::format("invalid stack size: must be at least %d bytes")
% minimum_stacksize() ) );
if ( ! is_stack_unbound() && ( maximum_stacksize() < size) )
throw std::invalid_argument(
boost::str( boost::format("invalid stack size: must not be larger than %d bytes")
% maximum_stacksize() ) );
const std::size_t pages( page_count( size) + 1); // add +1 for guard page
std::size_t size_ = pages * pagesize();
const int fd( ::open("/dev/zero", O_RDONLY) );
BOOST_ASSERT( -1 != fd);
void * limit =
# if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
::mmap( 0, size_, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
# else
::mmap( 0, size_, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
# endif
::close( fd);
if ( ! limit) throw std::bad_alloc();
const int result( ::mprotect( limit, pagesize(), PROT_NONE) );
BOOST_ASSERT( 0 == result);
return static_cast< char * >( limit) + size_;
}
void
stack_allocator::deallocate( void * vp, std::size_t size) const
{
if ( vp)
{
const std::size_t pages( page_count( size) + 1); // add +1 for guard page
std::size_t size_ = pages * pagesize();
BOOST_ASSERT( 0 < size && 0 < size_);
void * limit = static_cast< char * >( vp) - size_;
::munmap( limit, size_);
}
}
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_CONTEXT_SOURCE
#include <boost/context/stack_allocator.hpp>
extern "C" {
#include <windows.h>
}
#include <stdexcept>
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/format.hpp>
#include <boost/context/stack_utils.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
# if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable:4244 4267)
# endif
namespace boost {
namespace ctx {
void *
stack_allocator::allocate( std::size_t size) const
{
if ( minimum_stacksize() > size)
throw std::invalid_argument(
boost::str( boost::format("invalid stack size: must be at least %d bytes")
% minimum_stacksize() ) );
if ( ! is_stack_unbound() && ( maximum_stacksize() < size) )
throw std::invalid_argument(
boost::str( boost::format("invalid stack size: must not be larger than %d bytes")
% maximum_stacksize() ) );
const std::size_t pages( page_count( size) + 1); // add +1 for guard page
std::size_t size_ = pages * pagesize();
#ifndef BOOST_CONTEXT_FIBER
void * limit = ::VirtualAlloc( 0, size_, MEM_COMMIT, PAGE_READWRITE);
if ( ! limit) throw std::bad_alloc();
DWORD old_options;
const BOOL result = ::VirtualProtect(
limit, pagesize(), PAGE_READWRITE | PAGE_GUARD /*PAGE_NOACCESS*/, & old_options);
BOOST_ASSERT( FALSE != result);
return static_cast< char * >( limit) + size_;
#endif
}
void
stack_allocator::deallocate( void * vp, std::size_t size) const
{
if ( vp)
{
const std::size_t pages( page_count( size) + 1); // add +1 for guard page
std::size_t size_ = pages * pagesize();
BOOST_ASSERT( 0 < size && 0 < size_);
void * limit = static_cast< char * >( vp) - size_;
::VirtualFree( limit, 0, MEM_RELEASE);
}
}
}}
# if defined(BOOST_MSVC)
# pragma warning(pop)
# endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_CONTEXT_SOURCE
#include <boost/context/stack_utils.hpp>
extern "C" {
#include <sys/resource.h>
#include <sys/time.h>
#include <unistd.h>
}
#include <cmath>
#include <csignal>
#include <boost/assert.hpp>
namespace {
static rlimit stacksize_limit_()
{
rlimit limit;
const int result = ::getrlimit( RLIMIT_STACK, & limit);
BOOST_ASSERT( 0 == result);
return limit;
}
static rlimit stacksize_limit()
{
static rlimit limit = stacksize_limit_();
return limit;
}
}
namespace boost {
namespace ctx {
BOOST_CONTEXT_DECL
std::size_t default_stacksize()
{
static std::size_t size = 256 * 1024;
return size;
}
BOOST_CONTEXT_DECL
std::size_t minimum_stacksize()
{ return SIGSTKSZ; }
BOOST_CONTEXT_DECL
std::size_t maximum_stacksize()
{
BOOST_ASSERT( ! is_stack_unbound() );
return static_cast< std::size_t >( stacksize_limit().rlim_max);
}
BOOST_CONTEXT_DECL
bool is_stack_unbound()
{ return RLIM_INFINITY == stacksize_limit().rlim_max; }
BOOST_CONTEXT_DECL
std::size_t pagesize()
{
static std::size_t pagesize( ::getpagesize() );
return pagesize;
}
BOOST_CONTEXT_DECL
std::size_t page_count( std::size_t stacksize)
{
return static_cast< std::size_t >(
std::ceil(
static_cast< float >( stacksize) / pagesize() ) );
}
}}
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_CONTEXT_SOURCE
#include <boost/context/stack_utils.hpp>
extern "C" {
#include <windows.h>
}
#include <cmath>
#include <csignal>
#include <boost/assert.hpp>
namespace {
static SYSTEM_INFO system_info_()
{
SYSTEM_INFO si;
::GetSystemInfo( & si);
return si;
}
static SYSTEM_INFO system_info()
{
static SYSTEM_INFO si = system_info_();
return si;
}
}
namespace boost {
namespace ctx {
BOOST_CONTEXT_DECL
std::size_t default_stacksize()
{
static std::size_t size = 256 * 1024;
return size;
}
BOOST_CONTEXT_DECL
std::size_t minimum_stacksize()
{
static std::size_t stacksize(
static_cast< std::size_t >( system_info().dwAllocationGranularity) );
return stacksize;
}
BOOST_CONTEXT_DECL
std::size_t maximum_stacksize()
{
BOOST_ASSERT( ! is_stack_unbound() );
static std::size_t stacksize = 8 * 1024 * 1024;
return stacksize;
}
// Windows seams not to provide a limit for the stacksize
BOOST_CONTEXT_DECL
bool is_stack_unbound()
{ return true; }
BOOST_CONTEXT_DECL
std::size_t pagesize()
{
static std::size_t pagesize(
static_cast< std::size_t >( system_info().dwPageSize) );
return pagesize;
}
BOOST_CONTEXT_DECL
std::size_t page_count( std::size_t stacksize)
{
return static_cast< std::size_t >(
std::ceil(
static_cast< float >( stacksize) / pagesize() ) );
}
}}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment