Commit 5b791d0e by FritzFlorian

Add custom 'fast fiber call' implementation to comparison.

We now cover all implementations that have a chance of being fast.
ARM implementations for our 'fast fiber call' are still missing. After we add them we decide on how to proceed.
parent 3a6b724d
Pipeline #1378 failed with stages
in 37 seconds
add_subdirectory(deboost.context)
if (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND CMAKE_SYSTEM_NAME STREQUAL "Linux") if (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
SET(SWITCH_ASSEMBLY "custom_stack_callback_x86_64.s") SET(SWITCH_ASSEMBLY "custom_stack_callback_x86_64.s")
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "arm" AND CMAKE_SYSTEM_NAME STREQUAL "Linux") SET(FIBER_ASSEMBLY "fiber_call_x86_64.s" "fiber_continue_x86_64.s")
SET(SWITCH_ASSEMBLY "custom_stack_callback_arm32.s") #elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "arm" AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
# SET(SWITCH_ASSEMBLY "custom_stack_callback_arm32.s" fiber_call.h fiber_call.cpp)
else () else ()
MESSAGE(FATAL_ERROR "Platform (${CMAKE_SYSTEM_PROCESSOR} on ${CMAKE_SYSTEM_NAME}) not supported! Please see Readme for instructions to port.") MESSAGE(FATAL_ERROR "Platform (${CMAKE_SYSTEM_PROCESSOR} on ${CMAKE_SYSTEM_NAME}) not supported! Please see Readme for instructions to port.")
endif () endif ()
add_executable(context_switch main.cpp ${SWITCH_ASSEMBLY} fiber_call_x86_64.s fiber_continue_x86_64.s) add_executable(context_switch
main.cpp
${SWITCH_ASSEMBLY}
fiber_call.h fiber_call.cpp
${FIBER_ASSEMBLY})
# Example for adding the library to your app (as a cmake project dependency) # Example for adding the library to your app (as a cmake project dependency)
target_link_libraries(context_switch) target_link_libraries(context_switch fcontext)
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
.build
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Microsoft Azure ApplicationInsights config file
ApplicationInsights.config
# Windows Store app package directory
AppPackages/
BundleArtifacts/
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
# FAKE - F# Make
.fake/
# PROJECT: fcontext
cmake_minimum_required(VERSION 3.0)
project(fcontext C)
if (NOT CMAKE_MODULE_PATH)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
endif()
if (MSVC)
enable_language(CXX ASM_MASM)
else()
enable_language(CXX ASM)
endif()
if(MSVC)
add_definitions(-D_ITERATOR_DEBUG_LEVEL=0)
add_definitions(-D_HAS_EXCEPTIONS=0)
endif()
add_definitions(-DBOOST_CONTEXT_EXPORT=)
set(HEADER "include/fcontext/fcontext.h")
set(SOURCES "source/stack.c")
# OS
if (APPLE)
set(CPU_ARCH "combined")
set(ASM_EXT "all_macho_gas.S")
elseif (ANDROID)
# Android
if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm")
set(CPU_ARCH "arm")
set(ASM_EXT "aapcs_elf_gas.S")
elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64")
set(CPU_ARCH "arm64")
set(ASM_EXT "aapcs_elf_gas.S")
elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "i686")
set(CPU_ARCH "i386")
set(ASM_EXT "sysv_elf_gas.S")
elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86_64")
set(CPU_ARCH "x86_64")
set(ASM_EXT "sysv_elf_gas.S")
endif()
elseif (UNIX)
# PC (x86/x64)
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
set(CPU_ARCH "x86_64")
else()
set(CPU_ARCH "i386")
endif()
set(ASM_EXT "sysv_elf_gas.S") # Linux/Unix
elseif (WIN32)
# Windows PC
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
set(CPU_ARCH "x86_64")
else()
set(CPU_ARCH "i386")
endif()
set(ASM_EXT "ms_pe_masm.asm")
endif()
set(ASM_SOURCES "asm/make_${CPU_ARCH}_${ASM_EXT}"
"asm/jump_${CPU_ARCH}_${ASM_EXT}"
"asm/ontop_${CPU_ARCH}_${ASM_EXT}")
add_library(fcontext STATIC ${SOURCES} ${ASM_SOURCES})
target_include_directories(fcontext
PRIVATE include/fcontext
INTERFACE include)
set_target_properties(fcontext PROPERTIES FOLDER Deps ${IOS_GENERAL_PROPERTIES})
install(TARGETS fcontext DESTINATION lib)
install(FILES ${HEADER} DESTINATION include/fcontext)
The MIT License (MIT)
Copyright (c) 2016 Sepehr Taghdisian
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
## deboost.context
"Deboostified" version of boost.context (coroutines), Plain and simple C API for context switching. Easy build on multiple platforms.
### Build
#### Currently supported platforms
- Windows (x86_64, Win32)
- Linux (x86_64/x86)
- OSX (x86_64/x86)
- Android (ARM/x86/ARM64/x86_64)
- iOS (Arm64, Arm7, x86_64, i386)
#### iOS
I've made an extra xcode project files for iOS ```projects/xcode/fcontext``` because I didn't know how to set different ASM files for each ARM architecture in cmake. So If you know how to do it, I'd be happy if you tell me.
So, you can use the included toolchain file or use your own, just define _IOS_ to include the xcode project instead of generating it with cmake.
```
cd deboost.context
mkdir .build
cd .build
cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/ios.toolchain.cmake -G Xcode
```
### Usage
Link your program with fcontext.lib/libfcontext.a and include the file _fcontext.h_.
See _include/fcontext/fcontext.h_ for API usage.
More info is available at: [boost.context](http://www.boost.org/doc/libs/1_60_0/libs/context/doc/html/index.html)
### Credits
- Boost.context: This library uses the code from boost.context [github](https://github.com/boostorg/context)
### Thanks
- Ali Salehi [github](https://github.com/lordhippo)
/*
Copyright Edward Nevill + Oliver Kowalke 2015
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 | 6 | 7 | *
* ------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
* ------------------------------------------------- *
* | x19 | x20 | x21 | x22 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
* ------------------------------------------------- *
* | x23 | x24 | x25 | x26 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
* ------------------------------------------------- *
* | x27 | x28 | FP | LR | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
* ------------------------------------------------- *
* | PC | align | | | *
* ------------------------------------------------- *
* *
*******************************************************/
.cpu generic+fp+simd
.text
.align 2
.global jump_fcontext
.type jump_fcontext, %function
jump_fcontext:
# prepare stack for GP + FPU
sub sp, sp, #0x70
# save x19-x30
stp x19, x20, [sp, #0x00]
stp x21, x22, [sp, #0x10]
stp x23, x24, [sp, #0x20]
stp x25, x26, [sp, #0x30]
stp x27, x28, [sp, #0x40]
stp x29, x30, [sp, #0x50]
# save LR as PC
str x30, [sp, #0x60]
# store RSP (pointing to context-data) in X0
mov x4, sp
# restore RSP (pointing to context-data) from X1
mov sp, x0
# load x19-x30
ldp x19, x20, [sp, #0x00]
ldp x21, x22, [sp, #0x10]
ldp x23, x24, [sp, #0x20]
ldp x25, x26, [sp, #0x30]
ldp x27, x28, [sp, #0x40]
ldp x29, x30, [sp, #0x50]
# return transfer_t from jump
# pass transfer_t as first arg in context function
# X0 == FCTX, X1 == DATA
mov x0, x4
# load pc
ldr x4, [sp, #0x60]
# restore stack from GP + FPU
add sp, sp, #0x70
ret x4
.size jump_fcontext,.-jump_fcontext
# Mark that we don't need executable stack.
.section .note.GNU-stack,"",%progbits
/*******************************************************
* *
* ------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
* ------------------------------------------------- *
* | x19 | x20 | x21 | x22 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
* ------------------------------------------------- *
* | x23 | x24 | x25 | x26 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
* ------------------------------------------------- *
* | x27 | x28 | FP | LR | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
* ------------------------------------------------- *
* | PC | align | | | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.globl _jump_fcontext
.balign 16
_jump_fcontext:
; prepare stack for GP + FPU
sub sp, sp, #0x70
; save x19-x30
stp x19, x20, [sp, #0x00]
stp x21, x22, [sp, #0x10]
stp x23, x24, [sp, #0x20]
stp x25, x26, [sp, #0x30]
stp x27, x28, [sp, #0x40]
stp fp, lr, [sp, #0x50]
; save LR as PC
str lr, [sp, #0x60]
; store RSP (pointing to context-data) in X0
mov x4, sp
; restore RSP (pointing to context-data) from X1
mov sp, x0
; load x19-x30
ldp x19, x20, [sp, #0x00]
ldp x21, x22, [sp, #0x10]
ldp x23, x24, [sp, #0x20]
ldp x25, x26, [sp, #0x30]
ldp x27, x28, [sp, #0x40]
ldp fp, lr, [sp, #0x50]
; return transfer_t from jump
; pass transfer_t as first arg in context function
; X0 == FCTX, X1 == DATA
mov x0, x4
; load pc
ldr x4, [sp, #0x60]
; restore stack from GP + FPU
add sp, sp, #0x70
ret x4
/*
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 | 6 | 7 | *
* ------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
* ------------------------------------------------- *
* |hiddn| v1 | v2 | v3 | v4 | v5 | v6 | v7 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
* ------------------------------------------------- *
* | v8 | lr | pc | FCTX| DATA| | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.globl jump_fcontext
.align 2
.type jump_fcontext,%function
jump_fcontext:
@ save LR as PC
push {lr}
@ save hidden,V1-V8,LR
push {a1,v1-v8,lr}
@ store RSP (pointing to context-data) in A1
mov a1, sp
@ restore RSP (pointing to context-data) from A2
mov sp, a2
@ restore hidden,V1-V8,LR
pop {a4,v1-v8,lr}
@ return transfer_t from jump
str a1, [a4, #0]
str a3, [a4, #4]
@ pass transfer_t as first arg in context function
@ A1 == FCTX, A2 == DATA
mov a2, a3
@ restore PC
pop {pc}
.size jump_fcontext,.-jump_fcontext
@ Mark that we don't need executable stack.
.section .note.GNU-stack,"",%progbits
/*
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 | 6 | 7 | *
* ------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
* ------------------------------------------------- *
* | sjlj|hiddn| v1 | v2 | v3 | v4 | v5 | v6 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
* ------------------------------------------------- *
* | v7 | v8 | lr | pc | FCTX| DATA| | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.globl _jump_fcontext
.align 2
_jump_fcontext:
@ save LR as PC
push {lr}
@ save hidden,V1-V8,LR
push {a1,v1-v8,lr}
@ locate TLS to save/restore SjLj handler
mrc p15, 0, v2, c13, c0, #3
bic v2, v2, #3
@ load TLS[__PTK_LIBC_DYLD_Unwind_SjLj_Key]
ldr v1, [v2, #8]
@ save SjLj handler
push {v1}
@ store RSP (pointing to context-data) in A1
mov a1, sp
@ restore RSP (pointing to context-data) from A2
mov sp, a2
@ r#estore SjLj handler
pop {v1}
@ store SjLj handler in TLS
str v1, [v2, #8]
@ restore hidden,V1-V8,LR
pop {a4,v1-v8,lr}
@ return transfer_t from jump
str a1, [a4, #0]
str a3, [a4, #4]
@ pass transfer_t as first arg in context function
@ A1 == FCTX, A2 == DATA
mov a2, a3
@ restore PC
pop {pc}
;/*
; 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 | 6 | 7 | *
; * ------------------------------------------------- *
; * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
; * ------------------------------------------------- *
; * |deall|limit| base|hiddn| v1 | v2 | v3 | v4 | *
; * ------------------------------------------------- *
; * ------------------------------------------------- *
; * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
; * ------------------------------------------------- *
; * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
; * ------------------------------------------------- *
; * | v5 | v6 | v7 | v8 | lr | pc | FCTX| DATA| *
; * ------------------------------------------------- *
; * *
; *******************************************************
AREA |.text|, CODE
ALIGN 4
EXPORT jump_fcontext
jump_fcontext PROC
; save LR as PC
push {lr}
; save hidden,V1-V8,LR
push {a1,v1-v8,lr}
; load TIB to save/restore thread size and limit.
; we do not need preserve CPU flag and can use it's arg register
mrc p15, #0, v1, c13, c0, #2
; save current stack base
ldr a5, [v1, #0x04]
push {a5}
; save current stack limit
ldr a5, [v1, #0x08]
push {a5}
; save current deallocation stack
ldr a5, [v1, #0xe0c]
push {a5}
; store RSP (pointing to context-data) in A1
mov a1, sp
; restore RSP (pointing to context-data) from A2
mov sp, a2
; restore deallocation stack
pop {a5}
str a5, [v1, #0xe0c]
; restore stack limit
pop {a5}
str a5, [v1, #0x08]
; restore stack base
pop {a5}
str a5, [v1, #0x04]
; restore hidden,V1-V8,LR
pop {a4,v1-v8,lr}
; return transfer_t from jump
str a1, [a4, #0]
str a3, [a4, #4]
; pass transfer_t as first arg in context function
; A1 == FCTX, A2 == DATA
mov a2, a3
; restore PC
pop {pc}
ENDP
END
/*
Copyright Sergue E. Leontiev 2013.
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)
*/
// Stub file for universal binary
#if defined(__arm__) || defined(__aarch64__) || defined(_M_ARM)
#if defined(__aarch64__)
#include "jump_arm64_aapcs_macho_gas.S"
#else
#include "jump_arm_aapcs_macho_gas.S"
#endif
#else
#if defined(__i386__)
#include "jump_i386_sysv_macho_gas.S"
#elif defined(__x86_64__)
#include "jump_x86_64_sysv_macho_gas.S"
#elif defined(__ppc__)
#include "jump_ppc32_sysv_macho_gas.S"
#elif defined(__ppc64__)
#include "jump_ppc64_sysv_macho_gas.S"
#else
#error "No arch's"
#endif
#endif
\ No newline at end of file
/*
Copyright Sergue E. Leontiev 2013.
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)
*/
// Stub file for universal binary
#if defined(__i386__)
#include "jump_i386_sysv_macho_gas.S"
#elif defined(__x86_64__)
#include "jump_x86_64_sysv_macho_gas.S"
#elif defined(__ppc__)
#include "jump_ppc32_sysv_macho_gas.S"
#elif defined(__ppc64__)
#include "jump_ppc64_sysv_macho_gas.S"
#else
#error "No arch's"
#endif
/*
Copyright Oliver Kowalke 2009.
Copyright Thomas Sailer 2013.
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 | 6 | 7 | *
* --------------------------------------------------------------------------------- *
* | 0h | 04h | 08h | 0ch | 010h | 014h | 018h | 01ch | *
* --------------------------------------------------------------------------------- *
* | fc_strg |fc_deallo| limit | base | fc_seh | EDI | ESI | EBX | *
* --------------------------------------------------------------------------------- *
* --------------------------------------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* --------------------------------------------------------------------------------- *
* | 020h | 024h | 028h | 02ch | 030h | 034h | 038h | 03ch | *
* --------------------------------------------------------------------------------- *
* | EBP | EIP | to | data | | EH NXT |SEH HNDLR| | *
* --------------------------------------------------------------------------------- *
*************************************************************************************/
.file "jump_i386_ms_pe_gas.asm"
.text
.p2align 4,,15
.globl _jump_fcontext
.def _jump_fcontext; .scl 2; .type 32; .endef
_jump_fcontext:
pushl %ebp /* save EBP */
pushl %ebx /* save EBX */
pushl %esi /* save ESI */
pushl %edi /* save EDI */
/* load NT_TIB */
movl %fs:(0x18), %edx
/* load current SEH exception list */
movl (%edx), %eax
push %eax
/* load current stack base */
movl 0x04(%edx), %eax
push %eax
/* load current stack limit */
movl 0x08(%edx), %eax
push %eax
/* load current dealloction stack */
movl 0xe0c(%edx), %eax
push %eax
/* load fiber local storage */
movl 0x10(%edx), %eax
push %eax
/* store ESP (pointing to context-data) in EAX */
movl %esp, %eax
/* first arg of jump_fcontext() == fcontext to jump to */
movl 0x28(%esp), %ecx
/* restore ESP (pointing to context-data) from EDX */
movl %ecx, %esp
/* load NT_TIB into ECX */
movl %fs:(0x18), %edx
/* restore fiber local storage */
popl %ecx
movl %ecx, 0x10(%edx)
/* restore current deallocation stack */
popl %ecx
movl %ecx, 0xe0c(%edx)
/* restore current stack limit */
popl %ecx
movl %ecx, 0x08(%edx)
/* restore current stack base */
popl %ecx
movl %ecx, 0x04(%edx)
/* restore current SEH exception list */
popl %ecx
movl %ecx, (%edx)
popl %edi /* save EDI */
popl %esi /* save ESI */
popl %ebx /* save EBX */
popl %ebp /* save EBP */
/* return transfer_t */
/* FCTX == EAX, DATA == EDX */
movl 0x2c(%eax), %edx
/* jump to context */
ret
.section .drectve
.ascii " -export:\"jump_fcontext\""
; 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 | 6 | 7 |
; ---------------------------------------------------------------------------------
; | 0h | 04h | 08h | 0ch | 010h | 014h | 018h | 01ch |
; ---------------------------------------------------------------------------------
; | fc_strg |fc_deallo| limit | base | fc_seh | EDI | ESI | EBX |
; ---------------------------------------------------------------------------------
; ---------------------------------------------------------------------------------
; | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
; ---------------------------------------------------------------------------------
; | 020h | 024h | 028h | 02ch | 030h | 034h | 038h | 03ch |
; ---------------------------------------------------------------------------------
; | EBP | EIP | to | data | | EH NXT |SEH HNDLR| |
; ---------------------------------------------------------------------------------
.386
.XMM
.model flat, c
.code
jump_fcontext PROC BOOST_CONTEXT_EXPORT
push ebp ; save EBP
push ebx ; save EBX
push esi ; save ESI
push edi ; save EDI
assume fs:nothing
; load NT_TIB into ECX
mov edx, fs:[018h]
assume fs:error
; load current SEH exception list
mov eax, [edx]
push eax
; load current stack base
mov eax, [edx+04h]
push eax
; load current stack limit
mov eax, [edx+08h]
push eax
; load current deallocation stack
mov eax, [edx+0e0ch]
push eax
; load fiber local storage
mov eax, [edx+010h]
push eax
; store ESP (pointing to context-data) in EAX
mov eax, esp
; firstarg of jump_fcontext() == fcontext to jump to
mov ecx, [esp+028h]
; restore ESP (pointing to context-data) from EAX
mov esp, ecx
assume fs:nothing
; load NT_TIB into EDX
mov edx, fs:[018h]
assume fs:error
; restore fiber local storage
pop ecx
mov [edx+010h], ecx
; restore current deallocation stack
pop ecx
mov [edx+0e0ch], ecx
; restore current stack limit
pop ecx
mov [edx+08h], ecx
; restore current stack base
pop ecx
mov [edx+04h], ecx
; restore current SEH exception list
pop ecx
mov [edx], ecx
pop edi ; save EDI
pop esi ; save ESI
pop ebx ; save EBX
pop ebp ; save EBP
; return transfer_t
; FCTX == EAX, DATA == EDX
mov edx, [eax+02ch]
; jump to context
ret
jump_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)
*/
/*****************************************************************************************
* *
* ----------------------------------------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ----------------------------------------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
* ----------------------------------------------------------------------------------- *
* | EDI | ESI | EBX | EBP | EIP | hidden | to | data | *
* ----------------------------------------------------------------------------------- *
* *
*****************************************************************************************/
.text
.globl jump_fcontext
.align 2
.type jump_fcontext,@function
jump_fcontext:
pushl %ebp /* save EBP */
pushl %ebx /* save EBX */
pushl %esi /* save ESI */
pushl %edi /* save EDI */
/* store fcontext_t in ECX */
movl %esp, %ecx
/* first arg of jump_fcontext() == fcontext to jump to */
movl 0x18(%esp), %eax
/* second arg of jump_fcontext() == data to be transferred */
movl 0x1c(%esp), %edx
/* restore ESP (pointing to context-data) from EAX */
movl %eax, %esp
/* address of returned transport_t */
movl 0x14(%esp), %eax
/* return parent fcontext_t */
movl %ecx, (%eax)
/* return data */
movl %edx, 0x4(%eax)
popl %edi /* restore EDI */
popl %esi /* restore ESI */
popl %ebx /* restore EBX */
popl %ebp /* restore EBP */
/* jump to context */
ret $4
.size jump_fcontext,.-jump_fcontext
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits
/*
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 | 6 | 7 | *
* ----------------------------------------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
* ----------------------------------------------------------------------------------- *
* | EDI | ESI | EBX | EBP | EIP | hidden | to | data | *
* ----------------------------------------------------------------------------------- *
* *
*****************************************************************************************/
.text
.globl _jump_fcontext
.align 2
_jump_fcontext:
pushl %ebp /* save EBP */
pushl %ebx /* save EBX */
pushl %esi /* save ESI */
pushl %edi /* save EDI */
/* store fcontext_t in ECX */
movl %esp, %ecx
/* first arg of jump_fcontext() == context jumping to */
movl 0x18(%esp), %eax
/* second arg of jump_fcontext() == data to be transferred */
movl 0x1c(%esp), %edx
/* restore ESP (pointing to context-data) from EAX */
movl %eax, %esp
/* address of returned transport_t */
movl 0x14(%esp), %eax
/* return parent fcontext_t */
movl %ecx, (%eax)
/* return data */
movl %edx, 0x4(%eax)
popl %edi /* restore EDI */
popl %esi /* restore ESI */
popl %ebx /* restore EBX */
popl %ebp /* restore EBP */
/* jump to context */
ret $4
/*
Copyright Sergue E. Leontiev 2013.
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)
*/
// Stub file for universal binary
#if defined(__i386__)
#include "jump_i386_sysv_macho_gas.S"
#elif defined(__x86_64__)
#include "jump_x86_64_sysv_macho_gas.S"
#else
#error "No arch's"
#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)
*/
/*******************************************************
* *
* ------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* | S0 | S1 | S2 | S3 | S4 | S5 | S6 | S7 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | FP |hiddn| RA | PC | GP | FCTX| DATA| | *
* ------------------------------------------------- *
* *
* *****************************************************/
.text
.globl jump_fcontext
.align 2
.type jump_fcontext,@function
.ent jump_fcontext
jump_fcontext:
# reserve space on stack
addiu $sp, $sp, -112
sw $s0, ($sp) # save S0
sw $s1, 4($sp) # save S1
sw $s2, 8($sp) # save S2
sw $s3, 12($sp) # save S3
sw $s4, 16($sp) # save S4
sw $s5, 20($sp) # save S5
sw $s6, 24($sp) # save S6
sw $s7, 28($sp) # save S7
sw $fp, 32($sp) # save FP
sw $a0, 36($sp) # save hidden, address of returned transfer_t
sw $ra, 40($sp) # save RA
sw $ra, 44($sp) # save RA as PC
# store SP (pointing to context-data) in A0
move $a0, $sp
# restore SP (pointing to context-data) from A1
move $sp, $a1
lw $s0, ($sp) # restore S0
lw $s1, 4($sp) # restore S1
lw $s2, 8($sp) # restore S2
lw $s3, 12($sp) # restore S3
lw $s4, 16($sp) # restore S4
lw $s5, 20($sp) # restore S5
lw $s6, 24($sp) # restore S6
lw $s7, 28($sp) # restore S7
lw $fp, 32($sp) # restore FP
lw $t0, 36($sp) # restore hidden, address of returned transfer_t
lw $ra, 40($sp) # restore RA
# load PC
lw $t9, 44($sp)
# adjust stack
addiu $sp, $sp, 112
# return transfer_t from jump
sw $a0, ($t0) # fctx of transfer_t
sw $a1, 4($t0) # data of transfer_t
# pass transfer_t as first arg in context function
# A0 == fctx, A1 == data
move $a1, $a2
# jump to context
jr $t9
.end jump_fcontext
.size jump_fcontext, .-jump_fcontext
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits
/*
Copyright Sergue E. Leontiev 2013.
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)
*/
// Stub file for universal binary
#if defined(__ppc__)
#include "jump_ppc32_sysv_macho_gas.S"
#elif defined(__ppc64__)
#include "jump_ppc64_sysv_macho_gas.S"
#else
#error "No arch's"
#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)
*/
/*******************************************************
* *
* ------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* | R13 | R14 | R15 | R16 | R17 | R18 | R19 | R20 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | R21 | R22 | R23 | R24 | R25 | R26 | R27 | R28 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
* ------------------------------------------------- *
* | R29 | R30 | R31 |hiddn| CR | LR | PC | FCTX| *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
* ------------------------------------------------- *
* | DATA| | | | | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.globl jump_fcontext
.align 2
.type jump_fcontext,@function
jump_fcontext:
# reserve space on stack
subi %r1, %r1, 92
stw %r13, 0(%r1) # save R13
stw %r14, 4(%r1) # save R14
stw %r15, 8(%r1) # save R15
stw %r16, 12(%r1) # save R16
stw %r17, 16(%r1) # save R17
stw %r18, 20(%r1) # save R18
stw %r19, 24(%r1) # save R19
stw %r20, 28(%r1) # save R20
stw %r21, 32(%r1) # save R21
stw %r22, 36(%r1) # save R22
stw %r23, 40(%r1) # save R23
stw %r24, 44(%r1) # save R24
stw %r25, 48(%r1) # save R25
stw %r26, 52(%r1) # save R26
stw %r27, 56(%r1) # save R27
stw %r28, 60(%r1) # save R28
stw %r29, 64(%r1) # save R29
stw %r30, 68(%r1) # save R30
stw %r31, 72(%r1) # save R31
stw %r3, 76(%r1) # save hidden
# save CR
mfcr %r0
stw %r0, 80(%r1)
# save LR
mflr %r0
stw %r0, 84(%r1)
# save LR as PC
stw %r0, 88(%r1)
# store RSP (pointing to context-data) in R6
mr %r6, %r1
# restore RSP (pointing to context-data) from R4
mr %r1, %r4
lwz %r13, 0(%r1) # restore R13
lwz %r14, 4(%r1) # restore R14
lwz %r15, 8(%r1) # restore R15
lwz %r16, 12(%r1) # restore R16
lwz %r17, 16(%r1) # restore R17
lwz %r18, 20(%r1) # restore R18
lwz %r19, 24(%r1) # restore R19
lwz %r20, 28(%r1) # restore R20
lwz %r21, 32(%r1) # restore R21
lwz %r22, 36(%r1) # restore R22
lwz %r23, 40(%r1) # restore R23
lwz %r24, 44(%r1) # restore R24
lwz %r25, 48(%r1) # restore R25
lwz %r26, 52(%r1) # restore R26
lwz %r27, 56(%r1) # restore R27
lwz %r28, 60(%r1) # restore R28
lwz %r29, 64(%r1) # restore R29
lwz %r30, 68(%r1) # restore R30
lwz %r31, 72(%r1) # restore R31
lwz %r3, 76(%r1) # restore hidden
# restore CR
lwz %r0, 80(%r1)
mtcr %r0
# restore LR
lwz %r0, 84(%r1)
mtlr %r0
# load PC
lwz %r0, 88(%r1)
# restore CTR
mtctr %r0
# adjust stack
addi %r1, %r1, 92
# return transfer_t
stw %r6, 0(%r3)
stw %r5, 4(%r3)
# jump to context
bctr
.size jump_fcontext, .-jump_fcontext
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits
/*
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 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* | R13 | R14 | R15 | R16 | R17 | R18 | R19 | R20 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | R21 | R22 | R23 | R24 | R25 | R26 | R27 | R28 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
* ------------------------------------------------- *
* | R29 | R30 | R31 |hiddn| CR | LR | PC | FCTX| *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
* ------------------------------------------------- *
* | DATA| | | | | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.globl _jump_fcontext
.align 2
_jump_fcontext:
; reserve space on stack
subi r1, r1, 92
stw r13, 0(r1) # save R13
stw r14, 4(r1) # save R14
stw r15, 8(r1) # save R15
stw r16, 12(r1) # save R16
stw r17, 16(r1) # save R17
stw r18, 20(r1) # save R18
stw r19, 24(r1) # save R19
stw r20, 28(r1) # save R20
stw r21, 32(r1) # save R21
stw r22, 36(r1) # save R22
stw r23, 40(r1) # save R23
stw r24, 44(r1) # save R24
stw r25, 48(r1) # save R25
stw r26, 52(r1) # save R26
stw r27, 56(r1) # save R27
stw r28, 60(r1) # save R28
stw r29, 64(r1) # save R29
stw r30, 68(r1) # save R30
stw r31, 72(r1) # save R31
stw r3, 76(r1) # save hidden
# save CR
mfcr r0
stw r0, 80(r1)
# save LR
mflr r0
stw r0, 84(r1)
# save LR as PC
stw r0, 88(r1)
# store RSP (pointing to context-data) in R6
mr r6, r1
# restore RSP (pointing to context-data) from R4
mr r1, r4
lwz r13, 0(r1) # restore R13
lwz r14, 4(r1) # restore R14
lwz r15, 8(r1) # restore R15
lwz r16, 12(r1) # restore R16
lwz r17, 16(r1) # restore R17
lwz r18, 20(r1) # restore R18
lwz r19, 24(r1) # restore R19
lwz r20, 28(r1) # restore R20
lwz r21, 32(r1) # restore R21
lwz r22, 36(r1) # restore R22
lwz r23, 40(r1) # restore R23
lwz r24, 44(r1) # restore R24
lwz r25, 48(r1) # restore R25
lwz r26, 52(r1) # restore R26
lwz r27, 56(r1) # restore R27
lwz r28, 60(r1) # restore R28
lwz r29, 64(r1) # restore R29
lwz r30, 68(r1) # restore R30
lwz r31, 72(r1) # restore R31
lwz r3, 76(r1) # restore hidden
# restore CR
lwz r0, 80(r1)
mtcr r0
# restore LR
lwz r0, 84(r1)
mtlr r0
# load PC
lwz r0, 88(r1)
# restore CTR
mtctr r0
# adjust stack
addi r1, r1, 92
# return transfer_t
stw r6, 0(r3)
stw r5, 4(r3)
# jump to context
bctr
.globl .jump_fcontext
.globl jump_fcontext[DS]
.align 2
.csect jump_fcontext[DS]
jump_fcontext:
.long .jump_fcontext
.jump_fcontext:
# reserve space on stack
subi 1, 1, 92
stw 13, 0(1) # save R13
stw 14, 4(1) # save R14
stw 15, 8(1) # save R15
stw 16, 12(1) # save R16
stw 17, 16(1) # save R17
stw 18, 20(1) # save R18
stw 19, 24(1) # save R19
stw 20, 28(1) # save R20
stw 21, 32(1) # save R21
stw 22, 36(1) # save R22
stw 23, 40(1) # save R23
stw 24, 44(1) # save R24
stw 25, 48(1) # save R25
stw 26, 52(1) # save R26
stw 27, 56(1) # save R27
stw 28, 60(1) # save R28
stw 29, 64(1) # save R29
stw 30, 68(1) # save R30
stw 31, 72(1) # save R31
stw 3, 76(1) # save hidden
# save CR
mfcr 0
stw 0, 80(1)
# save LR
mflr 0
stw 0, 84(1)
# save LR as PC
stw 0, 88(1)
# store RSP (pointing to context-data) in R6
mr 6, 1
# restore RSP (pointing to context-data) from R4
mr 1, 4
lwz 13, 0(1) # restore R13
lwz 14, 4(1) # restore R14
lwz 15, 8(1) # restore R15
lwz 16, 12(1) # restore R16
lwz 17, 16(1) # restore R17
lwz 18, 20(1) # restore R18
lwz 19, 24(1) # restore R19
lwz 20, 28(1) # restore R20
lwz 21, 32(1) # restore R21
lwz 22, 36(1) # restore R22
lwz 23, 40(1) # restore R23
lwz 24, 44(1) # restore R24
lwz 25, 48(1) # restore R25
lwz 26, 52(1) # restore R26
lwz 27, 56(1) # restore R27
lwz 28, 60(1) # restore R28
lwz 29, 64(1) # restore R29
lwz 30, 68(1) # restore R30
lwz 31, 72(1) # restore R31
lwz 3, 76(1) # restore hidden
# restore CR
lwz 0, 80(1)
mtcr 0
# restore LR
lwz 0, 84(1)
mtlr 0
# load PC
lwz 0, 88(1)
# restore CTR
mtctr 0
# adjust stack
addi 1, 1, 92
# return transfer_t
stw 6, 0(3)
stw 5, 4(3)
# jump to context
bctr
/*
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 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* | TOC | R14 | R15 | R16 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | R17 | R18 | R19 | R20 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
* ------------------------------------------------- *
* | R21 | R22 | R23 | R24 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
* ------------------------------------------------- *
* | R25 | R26 | R27 | R28 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
* ------------------------------------------------- *
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
* ------------------------------------------------- *
* | R29 | R30 | R31 | hidden | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
* ------------------------------------------------- *
* | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | *
* ------------------------------------------------- *
* | CR | LR | PC | back-chain| *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | *
* ------------------------------------------------- *
* | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | *
* ------------------------------------------------- *
* | cr saved | lr saved | compiler | linker | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | *
* ------------------------------------------------- *
* | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | *
* ------------------------------------------------- *
* | TOC saved | FCTX | DATA | | *
* ------------------------------------------------- *
* *
*******************************************************/
.globl jump_fcontext
#if _CALL_ELF == 2
.text
.align 2
jump_fcontext:
addis %r2, %r12, .TOC.-jump_fcontext@ha
addi %r2, %r2, .TOC.-jump_fcontext@l
.localentry jump_fcontext, . - jump_fcontext
#else
.section ".opd","aw"
.align 3
jump_fcontext:
# ifdef _CALL_LINUX
.quad .L.jump_fcontext,.TOC.@tocbase,0
.type jump_fcontext,@function
.text
.align 2
.L.jump_fcontext:
# else
.hidden .jump_fcontext
.globl .jump_fcontext
.quad .jump_fcontext,.TOC.@tocbase,0
.size jump_fcontext,24
.type .jump_fcontext,@function
.text
.align 2
.jump_fcontext:
# endif
#endif
# reserve space on stack
subi %r1, %r1, 184
#if _CALL_ELF != 2
std %r2, 0(%r1) # save TOC
#endif
std %r14, 8(%r1) # save R14
std %r15, 16(%r1) # save R15
std %r16, 24(%r1) # save R16
std %r17, 32(%r1) # save R17
std %r18, 40(%r1) # save R18
std %r19, 48(%r1) # save R19
std %r20, 56(%r1) # save R20
std %r21, 64(%r1) # save R21
std %r22, 72(%r1) # save R22
std %r23, 80(%r1) # save R23
std %r24, 88(%r1) # save R24
std %r25, 96(%r1) # save R25
std %r26, 104(%r1) # save R26
std %r27, 112(%r1) # save R27
std %r29, 120(%r1) # save R28
std %r29, 128(%r1) # save R29
std %r30, 136(%r1) # save R30
std %r31, 144(%r1) # save R31
std %r3, 152(%r1) # save hidden
# save CR
mfcr %r0
std %r0, 160(%r1)
# save LR
mflr %r0
std %r0, 168(%r1)
# save LR as PC
std %r0, 176(%r1)
# store RSP (pointing to context-data) in R6
mr %r6, %r1
# restore RSP (pointing to context-data) from R4
mr %r1, %r4
#if _CALL_ELF != 2
ld %r2, 0(%r1) # restore TOC
#endif
ld %r14, 8(%r1) # restore R14
ld %r15, 16(%r1) # restore R15
ld %r16, 24(%r1) # restore R16
ld %r17, 32(%r1) # restore R17
ld %r18, 40(%r1) # restore R18
ld %r19, 48(%r1) # restore R19
ld %r20, 56(%r1) # restore R20
ld %r21, 64(%r1) # restore R21
ld %r22, 72(%r1) # restore R22
ld %r23, 80(%r1) # restore R23
ld %r24, 88(%r1) # restore R24
ld %r25, 96(%r1) # restore R25
ld %r26, 104(%r1) # restore R26
ld %r27, 112(%r1) # restore R27
ld %r28, 120(%r1) # restore R28
ld %r29, 128(%r1) # restore R29
ld %r30, 136(%r1) # restore R30
ld %r31, 144(%r1) # restore R31
ld %r3, 152(%r1) # restore hidden
# restore CR
ld %r0, 160(%r1)
mtcr %r0
# restore LR
ld %r0, 168(%r1)
mtlr %r0
# load PC
ld %r12, 176(%r1)
# restore CTR
mtctr %r12
# adjust stack
addi %r1, %r1, 184
# return transfer_t
std %r6, 0(%r3)
std %r5, 8(%r3)
# jump to context
bctr
#if _CALL_ELF == 2
.size jump_fcontext, .-jump_fcontext
#else
# ifdef _CALL_LINUX
.size .jump_fcontext, .-.L.jump_fcontext
# else
.size .jump_fcontext, .-.jump_fcontext
# endif
#endif
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits
/*
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 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* | TOC | R14 | R15 | R16 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | R17 | R18 | R19 | R20 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
* ------------------------------------------------- *
* | R21 | R22 | R23 | R24 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
* ------------------------------------------------- *
* | R25 | R26 | R27 | R28 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
* ------------------------------------------------- *
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
* ------------------------------------------------- *
* | R29 | R30 | R31 | hidden | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
* ------------------------------------------------- *
* | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | *
* ------------------------------------------------- *
* | CR | LR | PC | back-chain| *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | *
* ------------------------------------------------- *
* | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | *
* ------------------------------------------------- *
* | cr saved | lr saved | compiler | linker | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | *
* ------------------------------------------------- *
* | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | *
* ------------------------------------------------- *
* | TOC saved | FCTX | DATA | | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.align 2
.globl jump_fcontext
_jump_fcontext:
; reserve space on stack
subi r1, r1, 184
std %r14, 8(%r1) ; save R14
std %r15, 16(%r1) ; save R15
std %r16, 24(%r1) ; save R16
std %r17, 32(%r1) ; save R17
std %r18, 40(%r1) ; save R18
std %r19, 48(%r1) ; save R19
std %r20, 56(%r1) ; save R20
std %r21, 64(%r1) ; save R21
std %r22, 72(%r1) ; save R22
std %r23, 80(%r1) ; save R23
std %r24, 88(%r1) ; save R24
std %r25, 96(%r1) ; save R25
std %r26, 104(%r1) ; save R26
std %r27, 112(%r1) ; save R27
std %r29, 120(%r1) ; save R28
std %r29, 128(%r1) ; save R29
std %r30, 136(%r1) ; save R30
std %r31, 144(%r1) ; save R31
std %r3, 152(%r1) ; save hidden
; save CR
mfcr r0
std r0, 160(r1)
; save LR
mflr r0
std r0, 168(r1)
; save LR as PC
std r0, 176(r1)
; store RSP (pointing to context-data) in R6
mr %r6, %r1
; restore RSP (pointing to context-data) from R4
mr r1, r4
ld %r14, 8(%r1) ; restore R14
ld %r15, 16(%r1) ; restore R15
ld %r16, 24(%r1) ; restore R16
ld %r17, 32(%r1) ; restore R17
ld %r18, 40(%r1) ; restore R18
ld %r19, 48(%r1) ; restore R19
ld %r20, 56(%r1) ; restore R20
ld %r21, 64(%r1) ; restore R21
ld %r22, 72(%r1) ; restore R22
ld %r23, 80(%r1) ; restore R23
ld %r24, 88(%r1) ; restore R24
ld %r25, 96(%r1) ; restore R25
ld %r26, 104(%r1) ; restore R26
ld %r27, 112(%r1) ; restore R27
ld %r28, 120(%r1) ; restore R28
ld %r29, 128(%r1) ; restore R29
ld %r30, 136(%r1) ; restore R30
ld %r31, 144(%r1) ; restore R31
ld %r3, 152(%r1) ; restore hidden
; restore CR
ld r0, 160(r1)
mtcr r0
; restore LR
ld r0, 168(r1)
mtlr r0
; load PC
ld r0, 176(r1)
; restore CTR
mtctr r0
; adjust stack
addi r1, r1, 184
; return transfer_t
std %r6, 0(%r3)
std %r5, 8(%r3)
; jump to context
bctr
.align 2
.globl .jump_fcontext
.jump_fcontext:
# reserve space on stack
subi 1, 1, 184
std 13, 0(1) # save R13
std 14, 8(1) # save R14
std 15, 16(1) # save R15
std 16, 24(1) # save R16
std 17, 32(1) # save R17
std 18, 40(1) # save R18
std 19, 48(1) # save R19
std 20, 56(1) # save R20
std 21, 64(1) # save R21
std 22, 72(1) # save R22
std 23, 80(1) # save R23
std 24, 88(1) # save R24
std 25, 96(1) # save R25
std 26, 104(1) # save R26
std 27, 112(1) # save R27
std 29, 120(1) # save R28
std 29, 128(1) # save R29
std 30, 136(1) # save R30
std 31, 144(1) # save R31
std 3, 152(1) # save hidden
# save CR
mfcr 0
std 0, 160(1)
# save LR
mflr 0
std 0, 168(1)
# save LR as PC
std 0, 176(1)
# store RSP (pointing to context-data) in R6
mr 6, 1
# restore RSP (pointing to context-data) from R4
mr 1, 4
ld 13, 0(1) # restore R13
ld 14, 8(1) # restore R14
ld 15, 16(1) # restore R15
ld 16, 24(1) # restore R16
ld 17, 32(1) # restore R17
ld 18, 40(1) # restore R18
ld 19, 48(1) # restore R19
ld 20, 56(1) # restore R20
ld 21, 64(1) # restore R21
ld 22, 72(1) # restore R22
ld 23, 80(1) # restore R23
ld 24, 88(1) # restore R24
ld 25, 96(1) # restore R25
ld 26, 104(1) # restore R26
ld 27, 112(1) # restore R27
ld 28, 120(1) # restore R28
ld 29, 128(1) # restore R29
ld 30, 136(1) # restore R30
ld 31, 144(1) # restore R31
ld 3, 152(1) # restore hidden
# restore CR
ld 0, 160(1)
mtcr 0
# restore LR
ld 0, 168(1)
mtlr 0
# load PC
ld 0, 176(1)
# restore CTR
mtctr 0
# adjust stack
addi 1, 1, 184
# return transfer_t
std 6, 0(3)
std 5, 8(3)
# jump to context
bctr
/*
Copyright Oliver Kowalke 2009.
Copyright Thomas Sailer 2013.
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 | 6 | 7 | *
* ---------------------------------------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
* ---------------------------------------------------------------------------------- *
* | fbr_strg | fc_dealloc | limit | base | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ---------------------------------------------------------------------------------- *
* | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
* ---------------------------------------------------------------------------------- *
* | R12 | R13 | R14 | R15 | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ---------------------------------------------------------------------------------- *
* | 0xe40 | 0x44 | 0x48 | 0x4c | 0x50 | 0x54 | 0x58 | 0x5c | *
* ---------------------------------------------------------------------------------- *
* | RDI | RSI | RBX | RBP | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ---------------------------------------------------------------------------------- *
* | 0x60 | 0x64 | 0x68 | 0x6c | 0x70 | 0x74 | 0x78 | 0x7c | *
* ---------------------------------------------------------------------------------- *
* | hidden | RIP | EXIT | parameter area | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 32 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | *
* ---------------------------------------------------------------------------------- *
* | 0x80 | 0x84 | 0x88 | 0x8c | 0x90 | 0x94 | 0x98 | 0x9c | *
* ---------------------------------------------------------------------------------- *
* | parameter area | FCTX | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | *
* ---------------------------------------------------------------------------------- *
* | 0xa0 | 0xa4 | 0xa8 | 0xac | 0xb0 | 0xb4 | 0xb8 | 0xbc | *
* ---------------------------------------------------------------------------------- *
* | DATA | | | | *
* ---------------------------------------------------------------------------------- *
* *
* ***********************************************************************************/
.file "jump_x86_64_ms_pe_gas.asm"
.text
.p2align 4,,15
.globl jump_fcontext
.def jump_fcontext; .scl 2; .type 32; .endef
.seh_proc jump_fcontext
jump_fcontext:
.seh_endprologue
pushq %rcx /* save hidden address of transport_t */
pushq %rbp /* save RBP */
pushq %rbx /* save RBX */
pushq %rsi /* save RSI */
pushq %rdi /* save RDI */
pushq %r15 /* save R15 */
pushq %r14 /* save R14 */
pushq %r13 /* save R13 */
pushq %r12 /* save R12 */
/* load NT_TIB */
movq %gs:(0x30), %r10
/* save current stack base */
movq 0x08(%r10), %rax
pushq %rax
/* save current stack limit */
movq 0x10(%r10), %rax
pushq %rax
/* save current deallocation stack */
movq 0x1478(%r10), %rax
pushq %rax
/* save fiber local storage */
movq 0x18(%r10), %rax
pushq %rax
/* preserve RSP (pointing to context-data) in R9 */
movq %rsp, %r9
/* restore RSP (pointing to context-data) from RDX */
movq %rdx, %rsp
/* load NT_TIB */
movq %gs:(0x30), %r10
/* restore fiber local storage */
popq %rax
movq %rax, 0x18(%r10)
/* restore deallocation stack */
popq %rax
movq %rax, 0x1478(%r10)
/* restore stack limit */
popq %rax
movq %rax, 0x10(%r10)
/* restore stack base */
popq %rax
movq %rax, 0x8(%r10)
popq %r12 /* restore R12 */
popq %r13 /* restore R13 */
popq %r14 /* restore R14 */
popq %r15 /* restore R15 */
popq %rdi /* restore RDI */
popq %rsi /* restore RSI */
popq %rbx /* restore RBX */
popq %rbp /* restore RBP */
popq %rax /* restore hidden address of transport_t */
/* restore return-address */
popq %r10
/* transport_t returned in RAX */
/* return parent fcontext_t */
movq %r9, (%rax)
/* return data */
movq %r8, 0x8(%rax)
/* transport_t as 1.arg of context-function */
movq %rax, %rcx
/* indirect jump to context */
jmp *%r10
.seh_endproc
.section .drectve
.ascii " -export:\"jump_fcontext\""
; 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 | 6 | 7 |
; ----------------------------------------------------------------------------------
; | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c |
; ----------------------------------------------------------------------------------
; | fbr_strg | fc_dealloc | limit | base |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
; ----------------------------------------------------------------------------------
; | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c |
; ----------------------------------------------------------------------------------
; | R12 | R13 | R14 | R15 |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
; ----------------------------------------------------------------------------------
; | 0xe40 | 0x44 | 0x48 | 0x4c | 0x50 | 0x54 | 0x58 | 0x5c |
; ----------------------------------------------------------------------------------
; | RDI | RSI | RBX | RBP |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
; ----------------------------------------------------------------------------------
; | 0x60 | 0x64 | 0x68 | 0x6c | 0x70 | 0x74 | 0x78 | 0x7c |
; ----------------------------------------------------------------------------------
; | hidden | RIP | EXIT | parameter area |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 32 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
; ----------------------------------------------------------------------------------
; | 0x80 | 0x84 | 0x88 | 0x8c | 0x90 | 0x94 | 0x98 | 0x9c |
; ----------------------------------------------------------------------------------
; | parameter area | FCTX |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |
; ----------------------------------------------------------------------------------
; | 0xa0 | 0xa4 | 0xa8 | 0xac | 0xb0 | 0xb4 | 0xb8 | 0xbc |
; ----------------------------------------------------------------------------------
; | DATA | | | |
; ----------------------------------------------------------------------------------
.code
jump_fcontext PROC BOOST_CONTEXT_EXPORT FRAME
.endprolog
push rcx ; save hidden address of transport_t
push rbp ; save RBP
push rbx ; save RBX
push rsi ; save RSI
push rdi ; save RDI
push r15 ; save R15
push r14 ; save R14
push r13 ; save R13
push r12 ; save R12
; load NT_TIB
mov r10, gs:[030h]
; save current stack base
mov rax, [r10+08h]
push rax
; save current stack limit
mov rax, [r10+010h]
push rax
; save current deallocation stack
mov rax, [r10+01478h]
push rax
; save fiber local storage
mov rax, [r10+018h]
push rax
; preserve RSP (pointing to context-data) in R9
mov r9, rsp
; restore RSP (pointing to context-data) from RDX
mov rsp, rdx
; load NT_TIB
mov r10, gs:[030h]
; restore fiber local storage
pop rax
mov [r10+018h], rax
; restore deallocation stack
pop rax
mov [r10+01478h], rax
; restore stack limit
pop rax
mov [r10+010h], rax
; restore stack base
pop rax
mov [r10+08h], rax
pop r12 ; restore R12
pop r13 ; restore R13
pop r14 ; restore R14
pop r15 ; restore R15
pop rdi ; restore RDI
pop rsi ; restore RSI
pop rbx ; restore RBX
pop rbp ; restore RBP
pop rax ; restore hidden address of transport_t
; restore return-address
pop r10
; transport_t returned in RAX
; return parent fcontext_t
mov [rax], r9
; return data
mov [rax+08h], r8
; transport_t as 1.arg of context-function
mov rcx, rax
; indirect jump to context
jmp r10
jump_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)
*/
/****************************************************************************************
* *
* ---------------------------------------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ---------------------------------------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
* ---------------------------------------------------------------------------------- *
* | R12 | R13 | R14 | R15 | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ---------------------------------------------------------------------------------- *
* | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
* ---------------------------------------------------------------------------------- *
* | RBX | RBP | RIP | EXIT | *
* ---------------------------------------------------------------------------------- *
* *
****************************************************************************************/
.text
.globl jump_fcontext
.type jump_fcontext,@function
.align 16
jump_fcontext:
pushq %rbp /* save RBP */
pushq %rbx /* save RBX */
pushq %r15 /* save R15 */
pushq %r14 /* save R14 */
pushq %r13 /* save R13 */
pushq %r12 /* save R12 */
/* store RSP (pointing to context-data) in RAX */
movq %rsp, %rax
/* restore RSP (pointing to context-data) from RDI */
movq %rdi, %rsp
popq %r12 /* restrore R12 */
popq %r13 /* restrore R13 */
popq %r14 /* restrore R14 */
popq %r15 /* restrore R15 */
popq %rbx /* restrore RBX */
popq %rbp /* restrore RBP */
/* restore return-address */
popq %r8
/* return transfer_t from jump */
/* RAX == fctx, RDX == data */
movq %rsi, %rdx
/* pass transfer_t as first arg in context function */
/* RDI == fctx, RSI == data */
movq %rax, %rdi
/* indirect jump to context */
jmp *%r8
.size jump_fcontext,.-jump_fcontext
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits
/*
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 | 6 | 7 | *
* ---------------------------------------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
* ---------------------------------------------------------------------------------- *
* | R12 | R13 | R14 | R15 | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ---------------------------------------------------------------------------------- *
* | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
* ---------------------------------------------------------------------------------- *
* | RBX | RBP | RIP | EXIT | *
* ---------------------------------------------------------------------------------- *
* *
****************************************************************************************/
.text
.globl _jump_fcontext
.align 8
_jump_fcontext:
pushq %rbp /* save RBP */
pushq %rbx /* save RBX */
pushq %r15 /* save R15 */
pushq %r14 /* save R14 */
pushq %r13 /* save R13 */
pushq %r12 /* save R12 */
/* store RSP (pointing to context-data) in RAX */
movq %rsp, %rax
/* restore RSP (pointing to context-data) from RDI */
movq %rdi, %rsp
popq %r12 /* restrore R12 */
popq %r13 /* restrore R13 */
popq %r14 /* restrore R14 */
popq %r15 /* restrore R15 */
popq %rbx /* restrore RBX */
popq %rbp /* restrore RBP */
/* restore return-address */
popq %r8
/* return transfer_t from jump */
/* RAX == fctx, RDX == data */
movq %rsi, %rdx
/* pass transfer_t as first arg in context function */
/* RDI == fctx, RSI == data */
movq %rax, %rdi
/* indirect jump to context */
jmp *%r8
/*
Copyright Edward Nevill + Oliver Kowalke 2015
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 | 6 | 7 | *
* ------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
* ------------------------------------------------- *
* | x19 | x20 | x21 | x22 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
* ------------------------------------------------- *
* | x23 | x24 | x25 | x26 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
* ------------------------------------------------- *
* | x27 | x28 | FP | LR | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
* ------------------------------------------------- *
* | PC | align | | | *
* ------------------------------------------------- *
* *
*******************************************************/
.cpu generic+fp+simd
.text
.align 2
.global make_fcontext
.type make_fcontext, %function
make_fcontext:
# shift address in x0 (allocated stack) to lower 16 byte boundary
and x0, x0, ~0xF
# reserve space for context-data on context-stack
sub x0, x0, #0x70
# third arg of make_fcontext() == address of context-function
# store address as a PC to jump in
str x2, [x0, #0x60]
# save address of finish as return-address for context-function
# will be entered after context-function returns (LR register)
adr x1, finish
str x1, [x0, #0x58]
ret x30 // return pointer to context-data (x0)
finish:
# exit code is zero
mov x0, #0
# exit application
bl _exit
.size make_fcontext,.-make_fcontext
# Mark that we don't need executable stack.
.section .note.GNU-stack,"",%progbits
/*******************************************************
* *
* ------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
* ------------------------------------------------- *
* | x19 | x20 | x21 | x22 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
* ------------------------------------------------- *
* | x23 | x24 | x25 | x26 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
* ------------------------------------------------- *
* | x27 | x28 | FP | LR | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
* ------------------------------------------------- *
* | PC | align | | | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.globl _make_fcontext
.balign 16
_make_fcontext:
; shift address in x0 (allocated stack) to lower 16 byte boundary
and x0, x0, ~0xF
; reserve space for context-data on context-stack
sub x0, x0, #0x70
; third arg of make_fcontext() == address of context-function
; store address as a PC to jump in
str x2, [x0, #0x60]
; compute abs address of label finish
; 0x0c = 3 instructions * size (4) before label 'finish'
; TODO: Numeric offset since llvm still does not support labels in ADR. Fix:
; http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140407/212336.html
adr x1, 0x0c
; save address of finish as return-address for context-function
; will be entered after context-function returns (LR register)
str x1, [x0, #0x58]
ret lr ; return pointer to context-data (x0)
finish:
; exit code is zero
mov x0, #0
; exit application
bl __exit
/*
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 | 6 | 7 | *
* ------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
* ------------------------------------------------- *
* |hiddn| v1 | v2 | v3 | v4 | v5 | v6 | v7 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
* ------------------------------------------------- *
* | v8 | lr | pc | FCTX| DATA| | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.globl make_fcontext
.align 2
.type make_fcontext,%function
make_fcontext:
@ shift address in A1 to lower 16 byte boundary
bic a1, a1, #15
@ reserve space for context-data on context-stack
sub a1, a1, #60
@ third arg of make_fcontext() == address of context-function
str a3, [a1, #40]
@ compute address of returned transfer_t
add a2, a1, #44
mov a3, a2
str a3, [a1, #0]
@ compute abs address of label finish
adr a2, finish
@ save address of finish as return-address for context-function
@ will be entered after context-function returns
str a2, [a1, #36]
bx lr @ return pointer to context-data
finish:
@ exit code is zero
mov a1, #0
@ exit application
bl _exit@PLT
.size make_fcontext,.-make_fcontext
@ Mark that we don't need executable stack.
.section .note.GNU-stack,"",%progbits
/*
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 | 6 | 7 | *
* ------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
* ------------------------------------------------- *
* | sjlj|hiddn| v1 | v2 | v3 | v4 | v5 | v6 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
* ------------------------------------------------- *
* | v7 | v8 | lr | pc | FCTX| DATA| | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.globl _make_fcontext
.align 2
_make_fcontext:
@ shift address in A1 to lower 16 byte boundary
bic a1, a1, #15
@ reserve space for context-data on context-stack
sub a1, a1, #64
@ third arg of make_fcontext() == address of context-function
str a3, [a1, #44]
@ compute address of returned transfer_t
add a2, a1, #48
mov a3, a2
str a3, [a1, #4]
@ compute abs address of label finish
adr a2, finish
@ save address of finish as return-address for context-function
@ will be entered after context-function returns
str a2, [a1, #40]
bx lr @ return pointer to context-data
finish:
@ exit code is zero
mov a1, #0
@ exit application
bl __exit
;/*
; 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 | 6 | 7 | *
; * ------------------------------------------------- *
; * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
; * ------------------------------------------------- *
; * |deall|limit| base|hiddn| v1 | v2 | v3 | v4 | *
; * ------------------------------------------------- *
; * ------------------------------------------------- *
; * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
; * ------------------------------------------------- *
; * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
; * ------------------------------------------------- *
; * | v5 | v6 | v7 | v8 | lr | pc | FCTX| DATA| *
; * ------------------------------------------------- *
; * *
; *******************************************************
AREA |.text|, CODE
ALIGN 4
EXPORT make_fcontext
IMPORT _exit
make_fcontext PROC
; first arg of make_fcontext() == top of context-stack
; save top of context-stack (base) A4
mov a4, a1
; shift address in A1 to lower 16 byte boundary
bic a1, a1, #0x0f
; reserve space for context-data on context-stack
sub a1, a1, #0x48
; save top address of context_stack as 'base'
str a4, [a1, #0x8]
; second arg of make_fcontext() == size of context-stack
; compute bottom address of context-stack (limit)
sub a4, a4, a2
; save bottom address of context-stack as 'limit'
str a4, [a1, #0x4]
; save bottom address of context-stack as 'dealloction stack'
str a4, [a1, #0x0]
; third arg of make_fcontext() == address of context-function
str a3, [a1, #0x34]
; compute address of returned transfer_t
add a2, a1, #0x38
mov a3, a2
str a3, [a1, #0xc]
; compute abs address of label finish
adr a2, finish
; save address of finish as return-address for context-function
; will be entered after context-function returns
str a2, [a1, #0x30]
bx lr ; return pointer to context-data
finish
; exit code is zero
mov a1, #0
; exit application
bl _exit
ENDP
END
/*
Copyright Sergue E. Leontiev 2013.
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)
*/
// Stub file for universal binary
#if defined(__arm__) || defined(__aarch64__) || defined(_M_ARM)
#if defined(__aarch64__)
#include "make_arm64_aapcs_macho_gas.S"
#else
#include "make_arm_aapcs_macho_gas.S"
#endif
#else
#if defined(__i386__)
#include "make_i386_sysv_macho_gas.S"
#elif defined(__x86_64__)
#include "make_x86_64_sysv_macho_gas.S"
#elif defined(__ppc__)
#include "make_ppc32_sysv_macho_gas.S"
#elif defined(__ppc64__)
#include "make_ppc64_sysv_macho_gas.S"
#else
#error "No arch's"
#endif
#endif
/*
Copyright Sergue E. Leontiev 2013.
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)
*/
// Stub file for universal binary
#if defined(__i386__)
#include "make_i386_sysv_macho_gas.S"
#elif defined(__x86_64__)
#include "make_x86_64_sysv_macho_gas.S"
#elif defined(__ppc__)
#include "make_ppc32_sysv_macho_gas.S"
#elif defined(__ppc64__)
#include "make_ppc64_sysv_macho_gas.S"
#else
#error "No arch's"
#endif
/*
Copyright Oliver Kowalke 2009.
Copyright Thomas Sailer 2013.
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 | 6 | 7 | *
* --------------------------------------------------------------------------------- *
* | 0h | 04h | 08h | 0ch | 010h | 014h | 018h | 01ch | *
* --------------------------------------------------------------------------------- *
* | fc_strg |fc_deallo| limit | base | fc_seh | EDI | ESI | EBX | *
* --------------------------------------------------------------------------------- *
* --------------------------------------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* --------------------------------------------------------------------------------- *
* | 020h | 024h | 028h | 02ch | 030h | 034h | 038h | 03ch | *
* --------------------------------------------------------------------------------- *
* | EBP | EIP | to | data | | EH NXT |SEH HNDLR| | *
* --------------------------------------------------------------------------------- *
*************************************************************************************/
.file "make_i386_ms_pe_gas.asm"
.text
.p2align 4,,15
.globl _make_fcontext
.def _make_fcontext; .scl 2; .type 32; .endef
_make_fcontext:
/* first arg of make_fcontext() == top of context-stack */
movl 0x04(%esp), %eax
/* reserve space for first argument of context-function */
/* EAX might already point to a 16byte border */
leal -0x08(%eax), %eax
/* shift address in EAX to lower 16 byte boundary */
andl $-16, %eax
/* reserve space for context-data on context-stack */
/* size for fc_mxcsr .. EIP + return-address for context-function */
/* on context-function entry: (ESP -0x4) % 8 == 0 */
/* additional space is required for SEH */
leal -0x48(%eax), %eax
/* first arg of make_fcontext() == top of context-stack */
movl 0x04(%esp), %ecx
/* save top address of context stack as 'base' */
movl %ecx, 0xc(%eax)
/* second arg of make_fcontext() == size of context-stack */
movl 0x08(%esp), %edx
/* negate stack size for LEA instruction (== substraction) */
negl %edx
/* compute bottom address of context stack (limit) */
leal (%ecx,%edx), %ecx
/* save bottom address of context-stack as 'limit' */
movl %ecx, 0x8(%eax)
/* save bottom address of context-stack as 'dealloction stack' */
movl %ecx, 0x4(%eax)
/* third arg of make_fcontext() == address of context-function */
/* stored in EBX */
movl 0xc(%esp), %ecx
movl %ecx, 0x1c(%eax)
/* compute abs address of label trampoline */
movl $trampoline, %ecx
/* save address of trampoline as return-address for context-function */
/* will be entered after calling jump_fcontext() first time */
movl %ecx, 0x24(%eax)
/* compute abs address of label finish */
movl $finish, %ecx
/* save address of finish as return-address for context-function */
/* will be entered after context-function returns */
movl %ecx, 0x20(%eax)
/* traverse current seh chain to get the last exception handler installed by Windows */
/* note that on Windows Server 2008 and 2008 R2, SEHOP is activated by default */
/* the exception handler chain is tested for the presence of ntdll.dll!FinalExceptionHandler */
/* at its end by RaiseException all seh andlers are disregarded if not present and the */
/* program is aborted */
/* load NT_TIB into ECX */
movl %fs:(0x0), %ecx
walk:
/* load 'next' member of current SEH into EDX */
movl (%ecx), %edx
/* test if 'next' of current SEH is last (== 0xffffffff) */
incl %edx
jz found
decl %edx
/* exchange content; ECX contains address of next SEH */
xchgl %ecx, %edx
/* inspect next SEH */
jmp walk
found:
/* load 'handler' member of SEH == address of last SEH handler installed by Windows */
movl 0x04(%ecx), %ecx
/* save address in ECX as SEH handler for context */
movl %ecx, 0x38(%eax)
/* set ECX to -1 */
movl $0xffffffff, %ecx
/* save ECX as next SEH item */
movl %ecx, 0x34(%eax)
/* load address of next SEH item */
leal 0x34(%eax), %ecx
/* save next SEH */
movl %ecx, 0x10(%eax)
/* return pointer to context-data */
ret
trampoline:
/* move transport_t for entering context-function */
/* FCTX == EAX, DATA == EDX */
movl %eax, (%esp)
movl %edx, 0x4(%esp)
/* label finish as return-address */
pushl %ebp
/* jump to context-function */
jmp *%ebx
finish:
/* ESP points to same address as ESP on entry of context function + 0x4 */
xorl %eax, %eax
/* exit code is zero */
movl %eax, (%esp)
/* exit application */
call __exit
hlt
.def __exit; .scl 2; .type 32; .endef /* standard C library function */
.section .drectve
.ascii " -export:\"make_fcontext\""
; 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 | 6 | 7 |
; ---------------------------------------------------------------------------------
; | 0h | 04h | 08h | 0ch | 010h | 014h | 018h | 01ch |
; ---------------------------------------------------------------------------------
; | fc_strg |fc_deallo| limit | base | fc_seh | EDI | ESI | EBX |
; ---------------------------------------------------------------------------------
; ---------------------------------------------------------------------------------
; | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
; ---------------------------------------------------------------------------------
; | 020h | 024h | 028h | 02ch | 030h | 034h | 038h | 03ch |
; ---------------------------------------------------------------------------------
; | EBP | EIP | to | data | | EH NXT |SEH HNDLR| |
; ---------------------------------------------------------------------------------
.386
.XMM
.model flat, c
; standard C library function
_exit PROTO, value:SDWORD
.code
make_fcontext PROC BOOST_CONTEXT_EXPORT
; first arg of make_fcontext() == top of context-stack
mov eax, [esp+04h]
; reserve space for first argument of context-function
; EAX might already point to a 16byte border
lea eax, [eax-08h]
; shift address in EAX to lower 16 byte boundary
and eax, -16
; reserve space for context-data on context-stack
; on context-function entry: (ESP -0x4) % 8 == 0
; additional space is required for SEH
lea eax, [eax-048h]
; first arg of make_fcontext() == top of context-stack
mov ecx, [esp+04h]
; save top address of context stack as 'base'
mov [eax+0ch], ecx
; second arg of make_fcontext() == size of context-stack
mov edx, [esp+08h]
; negate stack size for LEA instruction (== substraction)
neg edx
; compute bottom address of context stack (limit)
lea ecx, [ecx+edx]
; save bottom address of context-stack as 'limit'
mov [eax+08h], ecx
; save bottom address of context-stack as 'dealloction stack'
mov [eax+04h], ecx
; third arg of make_fcontext() == address of context-function
; stored in EBX
mov ecx, [esp+0ch]
mov [eax+01ch], ecx
; compute abs address of label trampoline
mov ecx, trampoline
; save address of trampoline as return-address for context-function
; will be entered after calling jump_fcontext() first time
mov [eax+024h], ecx
; compute abs address of label finish
mov ecx, finish
; save address of finish as return-address for context-function
; will be entered after context-function returns
mov [eax+020h], ecx
; traverse current seh chain to get the last exception handler installed by Windows
; note that on Windows Server 2008 and 2008 R2, SEHOP is activated by default
; the exception handler chain is tested for the presence of ntdll.dll!FinalExceptionHandler
; at its end by RaiseException all seh-handlers are disregarded if not present and the
; program is aborted
assume fs:nothing
; load NT_TIB into ECX
mov ecx, fs:[0h]
assume fs:error
walk:
; load 'next' member of current SEH into EDX
mov edx, [ecx]
; test if 'next' of current SEH is last (== 0xffffffff)
inc edx
jz found
dec edx
; exchange content; ECX contains address of next SEH
xchg edx, ecx
; inspect next SEH
jmp walk
found:
; load 'handler' member of SEH == address of last SEH handler installed by Windows
mov ecx, [ecx+04h]
; save address in ECX as SEH handler for context
mov [eax+038h], ecx
; set ECX to -1
mov ecx, 0ffffffffh
; save ECX as next SEH item
mov [eax+034h], ecx
; load address of next SEH item
lea ecx, [eax+034h]
; save next SEH
mov [eax+010h], ecx
ret ; return pointer to context-data
trampoline:
; move transport_t for entering context-function
; FCTX == EAX, DATA == EDX
mov [esp], eax
mov [esp+04h], edx
push ebp
; jump to context-function
jmp ebx
finish:
; exit code is zero
xor eax, eax
mov [esp], eax
; exit application
call _exit
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)
*/
/*****************************************************************************************
* *
* ----------------------------------------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ----------------------------------------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
* ----------------------------------------------------------------------------------- *
* | EDI | ESI | EBX | EBP | EIP | hidden | to | data | *
* ----------------------------------------------------------------------------------- *
* *
*****************************************************************************************/
.text
.globl make_fcontext
.align 2
.type make_fcontext,@function
make_fcontext:
/* first arg of make_fcontext() == top of context-stack */
movl 0x4(%esp), %eax
/* reserve space for first argument of context-function
rax might already point to a 16byte border */
leal -0x8(%eax), %eax
/* shift address in EAX to lower 16 byte boundary */
andl $-16, %eax
/* reserve space for context-data on context-stack */
leal -0x28(%eax), %eax
/* third arg of make_fcontext() == address of context-function */
/* stored in EBX */
movl 0xc(%esp), %ecx
movl %ecx, 0x8(%eax)
/* return transport_t */
/* FCTX == EDI, DATA == ESI */
leal (%eax), %ecx
movl %ecx, 0x14(%eax)
/* compute abs address of label trampoline */
call 1f
/* address of trampoline 1 */
1: popl %ecx
/* compute abs address of label trampoline */
addl $trampoline-1b, %ecx
/* save address of trampoline as return address */
/* will be entered after calling jump_fcontext() first time */
movl %ecx, 0x10(%eax)
/* compute abs address of label finish */
call 2f
/* address of label 2 */
2: popl %ecx
/* compute abs address of label finish */
addl $finish-2b, %ecx
/* save address of finish as return-address for context-function */
/* will be entered after context-function returns */
movl %ecx, 0xc(%eax)
ret /* return pointer to context-data */
trampoline:
/* move transport_t for entering context-function */
movl %edi, (%esp)
movl %esi, 0x4(%esp)
pushl %ebp
/* jump to context-function */
jmp *%ebx
finish:
call 3f
/* address of label 3 */
3: popl %ebx
/* compute address of GOT and store it in EBX */
addl $_GLOBAL_OFFSET_TABLE_+[.-3b], %ebx
/* exit code is zero */
xorl %eax, %eax
movl %eax, (%esp)
/* exit application */
call _exit@PLT
hlt
.size make_fcontext,.-make_fcontext
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits
/*
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 | 6 | 7 | *
* ----------------------------------------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
* ----------------------------------------------------------------------------------- *
* | EDI | ESI | EBX | EBP | EIP | hidden | to | data | *
* ----------------------------------------------------------------------------------- *
* *
*****************************************************************************************/
.text
.globl _make_fcontext
.align 2
_make_fcontext:
/* first arg of make_fcontext() == top of context-stack */
movl 0x4(%esp), %eax
/* reserve space for first argument of context-function
rax might already point to a 16byte border */
leal -0x8(%eax), %eax
/* shift address in EAX to lower 16 byte boundary */
andl $-16, %eax
/* reserve space for context-data on context-stack */
leal -0x28(%eax), %eax
/* thrid arg of make_fcontext() == address of context-function */
/* stored in EBX */
movl 0xc(%esp), %edx
movl %edx, 0x8(%eax)
/* return transport_t */
/* FCTX == EDI, DATA == ESI */
leal (%eax), %ecx
movl %ecx, 0x14(%eax)
/* compute abs address of label trampoline */
call 1f
/* address of trampoline 1 */
1: popl %ecx
/* compute abs address of label trampoline */
addl $trampoline-1b, %ecx
/* save address of trampoline as return address */
/* will be entered after calling jump_fcontext() first time */
movl %ecx, 0x10(%eax)
/* compute abs address of label finish */
call 2f
/* address of label 2 */
2: popl %ecx
/* compute abs address of label finish */
addl $finish-2b, %ecx
/* save address of finish as return-address for context-function */
/* will be entered after context-function returns */
movl %ecx, 0xc(%eax)
ret /* return pointer to context-data */
trampoline:
/* move transport_t for entering context-function */
movl %edi, (%esp)
movl %esi, 0x4(%esp)
pushl %ebp
/* jump to context-function */
jmp *%ebx
finish:
/* exit code is zero */
xorl %eax, %eax
movl %eax, (%esp)
/* exit application */
call __exit
hlt
/*
Copyright Sergue E. Leontiev 2013.
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)
*/
// Stub file for universal binary
#if defined(__i386__)
#include "make_i386_sysv_macho_gas.S"
#elif defined(__x86_64__)
#include "make_x86_64_sysv_macho_gas.S"
#else
#error "No arch's"
#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)
*/
/*******************************************************
* *
* ------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* | S0 | S1 | S2 | S3 | S4 | S5 | S6 | S7 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | FP |hiddn| RA | PC | GP | FCTX| DATA| | *
* ------------------------------------------------- *
* *
* *****************************************************/
.text
.globl make_fcontext
.align 2
.type make_fcontext,@function
.ent make_fcontext
make_fcontext:
#ifdef __PIC__
.set noreorder
.cpload $t9
.set reorder
#endif
# first arg of make_fcontext() == top address of context-stack
move $v0, $a0
# shift address in A0 to lower 16 byte boundary
move $v1, $v0
li $v0, -16 # 0xfffffffffffffff0
and $v0, $v1, $v0
# reserve space for context-data on context-stack
# including 48 byte of shadow space (sp % 16 == 0)
addiu $v0, $v0, -112
# third arg of make_fcontext() == address of context-function
sw $a2, 44($v0)
# save global pointer in context-data
sw $gp, 48($v0)
# compute address of returned transfer_t
addiu $t0, $v0, 52
sw $t0, 36($v0)
# compute abs address of label finish
la $t9, finish
# save address of finish as return-address for context-function
# will be entered after context-function returns
sw $t9, 40($v0)
jr $ra # return pointer to context-data
finish:
lw $gp, 0($sp)
# allocate stack space (contains shadow space for subroutines)
addiu $sp, $sp, -32
# save return address
sw $ra, 28($sp)
# restore GP (global pointer)
# move $gp, $s1
# exit code is zero
move $a0, $zero
# address of exit
lw $t9, %call16(_exit)($gp)
# exit application
jalr $t9
.end make_fcontext
.size make_fcontext, .-make_fcontext
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits
/*
Copyright Sergue E. Leontiev 2013.
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)
*/
// Stub file for universal binary
#if defined(__ppc__)
#include "make_ppc32_sysv_macho_gas.S"
#elif defined(__ppc64__)
#include "make_ppc64_sysv_macho_gas.S"
#else
#error "No arch's"
#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)
*/
/******************************************************
* *
* ------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* | R13 | R14 | R15 | R16 | R17 | R18 | R19 | R20 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | R21 | R22 | R23 | R24 | R25 | R26 | R27 | R28 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
* ------------------------------------------------- *
* | R29 | R30 | R31 |hiddn| CR | LR | PC |bchai| *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
* ------------------------------------------------- *
* |linkr| FCTX| DATA| | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.globl make_fcontext
.align 2
.type make_fcontext,@function
make_fcontext:
# save return address into R6
mflr %r6
# first arg of make_fcontext() == top address of context-function
# shift address in R3 to lower 16 byte boundary
clrrwi %r3, %r3, 4
# reserve space for context-data on context-stack
# including 64 byte of linkage + parameter area (R1 % 16 == 0)
subi %r3, %r3, 172
# third arg of make_fcontext() == address of context-function
stw %r5, 88(%r3)
# set back-chain to zero
li %r0, 0
stw %r0, 92(%r3)
# compute address of returned transfer_t
addi %r0, %r3, 100
mr %r4, %r0
stw %r4, 76(%r3)
# load LR
mflr %r0
# jump to label 1
bl 1f
1:
# load LR into R4
mflr %r4
# compute abs address of label finish
addi %r4, %r4, finish - 1b
# restore LR
mtlr %r0
# save address of finish as return-address for context-function
# will be entered after context-function returns
stw %r4, 84(%r3)
# restore return address from R6
mtlr %r6
blr # return pointer to context-data
finish:
# save return address into R0
mflr %r0
# save return address on stack, set up stack frame
stw %r0, 4(%r1)
# allocate stack space, R1 % 16 == 0
stwu %r1, -16(%r1)
# exit code is zero
li %r3, 0
# exit application
bl _exit@plt
.size make_fcontext, .-make_fcontext
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits
/*
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 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* | R13 | R14 | R15 | R16 | R17 | R18 | R19 | R20 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | R21 | R22 | R23 | R24 | R25 | R26 | R27 | R28 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
* ------------------------------------------------- *
* | R29 | R30 | R31 |hiddn| CR | LR | PC |bchai| *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
* ------------------------------------------------- *
* |linkr| FCTX| DATA| | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.globl _make_fcontext
.align 2
_make_fcontext:
; save return address into R6
mflr r6
; first arg of make_fcontext() == top address of context-function
; shift address in R3 to lower 16 byte boundary
clrrwi r3, r3, 4
; reserve space for context-data on context-stack
; including 64 byte of linkage + parameter area (R1 % 16 == 0)
subi r3, r3, 172
; third arg of make_fcontext() == address of context-function
stw r5, 88(r3)
; set back-chain to zero
li r0, 0
stw r0, 92(r3)
; compute address of returned transfer_t
addi r0, r3, 100
mr r4, r0
stw r4, 76(r3)
; load LR
mflr r0
; jump to label 1
bl l1
l1:
; load LR into R4
mflr r4
; compute abs address of label finish
addi r4, r4, lo16((finish - .)+4)
# restore LR
mtlr r0
; save address of finish as return-address for context-function
; will be entered after context-function returns
stw r4, 84(r3)
; restore return address from R6
mtlr r6
blr ; return pointer to context-data
finish:
; save return address into R0
mflr r0
; save return address on stack, set up stack frame
stw r0, 4(r1)
; allocate stack space, R1 % 16 == 0
stwu r1, -16(r1)
; exit code is zero
li r3, 0
; exit application
bl __exit
.globl make_fcontext[DS]
.globl .make_fcontext[PR]
.align 2
.csect make_fcontext[DS]
make_fcontext:
.long .make_fcontext[PR]
.csect .make_fcontext[PR], 3
#.make_fcontext:
# save return address into R6
mflr 6
# first arg of make_fcontext() == top address of context-function
# shift address in R3 to lower 16 byte boundary
clrrwi 3, 3, 4
# reserve space for context-data on context-stack
# including 64 byte of linkage + parameter area (R1 % 16 == 0)
subi 3, 3, 172
# third arg of make_fcontext() == address of context-function
stw 5, 88(3)
# set back-chain to zero
li 0, 0
stw 0, 92(3)
# compute address of returned transfer_t
addi 0, 3, 100
mr 4, 0
stw 4, 76(3)
# load LR
mflr 0
# jump to label 1
bl .Label
.Label:
# load LR into R4
mflr 4
# compute abs address of label .L_finish
addi 4, 4, .L_finish - .Label
# restore LR
mtlr 0
# save address of finish as return-address for context-function
# will be entered after context-function returns
stw 4, 84(3)
# restore return address from R6
mtlr 6
blr # return pointer to context-data
.L_finish:
# save return address into R0
mflr 0
# save return address on stack, set up stack frame
stw 0, 4(1)
# allocate stack space, R1 % 16 == 0
stwu 1, -16(1)
# exit code is zero
li 3, 0
# exit application
bl ._exit
nop
/*
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 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* | TOC | R14 | R15 | R16 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | R17 | R18 | R19 | R20 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
* ------------------------------------------------- *
* | R21 | R22 | R23 | R24 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
* ------------------------------------------------- *
* | R25 | R26 | R27 | R28 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
* ------------------------------------------------- *
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
* ------------------------------------------------- *
* | R29 | R30 | R31 | hidden | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
* ------------------------------------------------- *
* | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | *
* ------------------------------------------------- *
* | CR | LR | PC | back-chain| *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | *
* ------------------------------------------------- *
* | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | *
* ------------------------------------------------- *
* | cr saved | lr saved | compiler | linker | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | *
* ------------------------------------------------- *
* | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | *
* ------------------------------------------------- *
* | TOC saved | FCTX | DATA | | *
* ------------------------------------------------- *
* *
*******************************************************/
.globl make_fcontext
#if _CALL_ELF == 2
.text
.align 2
make_fcontext:
addis %r2, %r12, .TOC.-make_fcontext@ha
addi %r2, %r2, .TOC.-make_fcontext@l
.localentry make_fcontext, . - make_fcontext
#else
.section ".opd","aw"
.align 3
make_fcontext:
# ifdef _CALL_LINUX
.quad .L.make_fcontext,.TOC.@tocbase,0
.type make_fcontext,@function
.text
.align 2
.L.make_fcontext:
# else
.hidden .make_fcontext
.globl .make_fcontext
.quad .make_fcontext,.TOC.@tocbase,0
.size make_fcontext,24
.type .make_fcontext,@function
.text
.align 2
.make_fcontext:
# endif
#endif
# save return address into R6
mflr %r6
# first arg of make_fcontext() == top address of context-stack
# shift address in R3 to lower 16 byte boundary
clrrdi %r3, %r3, 4
# reserve space for context-data on context-stack
# including 64 byte of linkage + parameter area (R1 % 16 == 0)
subi %r3, %r3, 248
# third arg of make_fcontext() == address of context-function
# entry point (ELFv2) or descriptor (ELFv1)
#if _CALL_ELF == 2
# save address of context-function entry point
std %r5, 176(%r3)
#else
# save address of context-function entry point
ld %r4, 0(%r5)
std %r4, 176(%r3)
# save TOC of context-function
ld %r4, 8(%r5)
std %r4, 0(%r3)
#endif
# set back-chain to zero
li %r0, 0
std %r0, 184(%r3)
# compute address of returned transfer_t
addi %r0, %r3, 232
mr %r4, %r0
std %r4, 152(%r3)
# load LR
mflr %r0
# jump to label 1
bl 1f
1:
# load LR into R4
mflr %r4
# compute abs address of label finish
addi %r4, %r4, finish - 1b
# restore LR
mtlr %r0
# save address of finish as return-address for context-function
# will be entered after context-function returns
std %r4, 168(%r3)
# restore return address from R6
mtlr %r6
blr # return pointer to context-data
finish:
# save return address into R0
mflr %r0
# save return address on stack, set up stack frame
std %r0, 8(%r1)
# allocate stack space, R1 % 16 == 0
stdu %r1, -32(%r1)
# exit code is zero
li %r3, 0
# exit application
bl _exit
nop
#if _CALL_ELF == 2
.size make_fcontext, .-make_fcontext
#else
# ifdef _CALL_LINUX
.size .make_fcontext, .-.L.make_fcontext
# else
.size .make_fcontext, .-.make_fcontext
# endif
#endif
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits
/*
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 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* | TOC | R14 | R15 | R16 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | R17 | R18 | R19 | R20 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
* ------------------------------------------------- *
* | R21 | R22 | R23 | R24 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
* ------------------------------------------------- *
* | R25 | R26 | R27 | R28 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
* ------------------------------------------------- *
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
* ------------------------------------------------- *
* | R29 | R30 | R31 | hidden | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
* ------------------------------------------------- *
* | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | *
* ------------------------------------------------- *
* | CR | LR | PC | back-chain| *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | *
* ------------------------------------------------- *
* | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | *
* ------------------------------------------------- *
* | cr saved | lr saved | compiler | linker | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | *
* ------------------------------------------------- *
* | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | *
* ------------------------------------------------- *
* | TOC saved | FCTX | DATA | | *
* ------------------------------------------------- *
* *
.text
.globl _make_fcontext
_make_fcontext:
; save return address into R6
mflr r6
; first arg of make_fcontext() == top address of context-function
; shift address in R3 to lower 16 byte boundary
clrrwi r3, r3, 4
; reserve space for context-data on context-stack
; including 64 byte of linkage + parameter area (R1 16 == 0)
subi r3, r3, 248
; third arg of make_fcontext() == address of context-function
stw r5, 176(r3)
; set back-chain to zero
li %r0, 0
std %r0, 184(%r3)
; compute address of returned transfer_t
addi %r0, %r3, 232
mr %r4, %r0
std %r4, 152(%r3)
; load LR
mflr r0
; jump to label 1
bl l1
l1:
; load LR into R4
mflr r4
; compute abs address of label finish
addi r4, r4, lo16((finish - .) + 4)
; restore LR
mtlr r0
; save address of finish as return-address for context-function
; will be entered after context-function returns
std r4, 168(r3)
; restore return address from R6
mtlr r6
blr ; return pointer to context-data
finish:
; save return address into R0
mflr r0
; save return address on stack, set up stack frame
stw r0, 8(r1)
; allocate stack space, R1 16 == 0
stwu r1, -32(r1)
; set return value to zero
li r3, 0
; exit application
bl __exit
nop
.globl make_fcontext[DS]
.globl .make_fcontext[PR]
.align 2
.csect .make_fcontext[PR], 3
.globl _make_fcontext
#._make_fcontext:
# save return address into R6
mflr 6
# first arg of make_fcontext() == top address of context-function
# shift address in R3 to lower 16 byte boundary
clrrwi 3, 3, 4
# reserve space for context-data on context-stack
# including 64 byte of linkage + parameter area (R1 % 16 == 0)
subi 3, 3, 248
# third arg of make_fcontext() == address of context-function
stw 5, 176(3)
# set back-chain to zero
li 0, 0
std 0, 184(3)
# compute address of returned transfer_t
addi 0, 3, 232
mr 4, 0
std 4, 152(3)
# load LR
mflr 0
# jump to label 1
bl .Label
.Label:
# load LR into R4
mflr 4
# compute abs address of label .L_finish
addi 4, 4, .L_finish - .Label
# restore LR
mtlr 0
# save address of finish as return-address for context-function
# will be entered after context-function returns
stw 4, 168(3)
# restore return address from R6
mtlr 6
blr # return pointer to context-data
.L_finish:
# save return address into R0
mflr 0
# save return address on stack, set up stack frame
stw 0, 8(1)
# allocate stack space, R1 % 16 == 0
stwu 1, -32(1)
# exit code is zero
li 3, 0
# exit application
bl ._exit
nop
/*
Copyright Oliver Kowalke 2009.
Copyright Thomas Sailer 2013.
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 | 6 | 7 | *
* ---------------------------------------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
* ---------------------------------------------------------------------------------- *
* | fbr_strg | fc_dealloc | limit | base | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ---------------------------------------------------------------------------------- *
* | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
* ---------------------------------------------------------------------------------- *
* | R12 | R13 | R14 | R15 | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ---------------------------------------------------------------------------------- *
* | 0xe40 | 0x44 | 0x48 | 0x4c | 0x50 | 0x54 | 0x58 | 0x5c | *
* ---------------------------------------------------------------------------------- *
* | RDI | RSI | RBX | RBP | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ---------------------------------------------------------------------------------- *
* | 0x60 | 0x64 | 0x68 | 0x6c | 0x70 | 0x74 | 0x78 | 0x7c | *
* ---------------------------------------------------------------------------------- *
* | hidden | RIP | EXIT | parameter area | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 32 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | *
* ---------------------------------------------------------------------------------- *
* | 0x80 | 0x84 | 0x88 | 0x8c | 0x90 | 0x94 | 0x98 | 0x9c | *
* ---------------------------------------------------------------------------------- *
* | parameter area | FCTX | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | *
* ---------------------------------------------------------------------------------- *
* | 0xa0 | 0xa4 | 0xa8 | 0xac | 0xb0 | 0xb4 | 0xb8 | 0xbc | *
* ---------------------------------------------------------------------------------- *
* | DATA | | | | *
* ---------------------------------------------------------------------------------- *
* *
* ***********************************************************************************/
.file "make_x86_64_ms_pe_gas.asm"
.text
.p2align 4,,15
.globl make_fcontext
.def make_fcontext; .scl 2; .type 32; .endef
.seh_proc make_fcontext
make_fcontext:
.seh_endprologue
/* first arg of make_fcontext() == top of context-stack */
movq %rcx, %rax
/* shift address in RAX to lower 16 byte boundary */
/* == pointer to fcontext_t and address of context stack */
andq $-16, %rax
/* reserve space for context-data on context-stack */
/* on context-function entry: (RSP -0x8) % 16 == 0 */
leaq -0xb8(%rax), %rax
/* third arg of make_fcontext() == address of context-function */
movq %r8, 0x68(%rax)
/* first arg of make_fcontext() == top of context-stack */
/* save top address of context stack as 'base' */
movq %rcx, 0x18(%rax)
/* second arg of make_fcontext() == size of context-stack */
/* negate stack size for LEA instruction (== substraction) */
negq %rdx
/* compute bottom address of context stack (limit) */
leaq (%rcx,%rdx), %rcx
/* save bottom address of context stack as 'limit' */
movq %rcx, 0x10(%rax)
/* save address of context stack limit as 'dealloction stack' */
movq %rcx, 0x8(%rax)
/* compute address of transport_t */
leaq 0x98(%rax), %rcx
/* store address of transport_t in hidden field */
movq %rcx, 0x60(%rax)
/* compute abs address of label finish */
leaq finish(%rip), %rcx
/* save address of finish as return-address for context-function */
/* will be entered after context-function returns */
movq %rcx, 0x70(%rax)
ret /* return pointer to context-data */
finish:
/* 32byte shadow-space for _exit() */
andq $-32, %rsp
/* 32byte shadow-space for _exit() are */
/* already reserved by make_fcontext() */
/* exit code is zero */
xorq %rcx, %rcx
/* exit application */
call _exit
hlt
.seh_endproc
.def _exit; .scl 2; .type 32; .endef /* standard C library function */
.section .drectve
.ascii " -export:\"make_fcontext\""
; 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 | 6 | 7 |
; ----------------------------------------------------------------------------------
; | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c |
; ----------------------------------------------------------------------------------
; | fbr_strg | fc_dealloc | limit | base |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
; ----------------------------------------------------------------------------------
; | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c |
; ----------------------------------------------------------------------------------
; | R12 | R13 | R14 | R15 |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
; ----------------------------------------------------------------------------------
; | 0xe40 | 0x44 | 0x48 | 0x4c | 0x50 | 0x54 | 0x58 | 0x5c |
; ----------------------------------------------------------------------------------
; | RDI | RSI | RBX | RBP |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
; ----------------------------------------------------------------------------------
; | 0x60 | 0x64 | 0x68 | 0x6c | 0x70 | 0x74 | 0x78 | 0x7c |
; ----------------------------------------------------------------------------------
; | hidden | RIP | EXIT | parameter area |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 32 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
; ----------------------------------------------------------------------------------
; | 0x80 | 0x84 | 0x88 | 0x8c | 0x90 | 0x94 | 0x98 | 0x9c |
; ----------------------------------------------------------------------------------
; | parameter area | FCTX |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |
; ----------------------------------------------------------------------------------
; | 0xa0 | 0xa4 | 0xa8 | 0xac | 0xb0 | 0xb4 | 0xb8 | 0xbc |
; ----------------------------------------------------------------------------------
; | DATA | | | |
; ----------------------------------------------------------------------------------
; standard C library function
EXTERN _exit:PROC
.code
; generate function table entry in .pdata and unwind information in
make_fcontext PROC BOOST_CONTEXT_EXPORT FRAME
; .xdata for a function's structured exception handling unwind behavior
.endprolog
; first arg of make_fcontext() == top of context-stack
mov rax, rcx
; shift address in RAX to lower 16 byte boundary
; == pointer to fcontext_t and address of context stack
and rax, -16
; reserve space for context-data on context-stack
; on context-function entry: (RSP -0x8) % 16 == 0
sub rax, 0b8h
; third arg of make_fcontext() == address of context-function
mov [rax+068h], r8
; first arg of make_fcontext() == top of context-stack
; save top address of context stack as 'base'
mov [rax+018h], rcx
; second arg of make_fcontext() == size of context-stack
; negate stack size for LEA instruction (== substraction)
neg rdx
; compute bottom address of context stack (limit)
lea rcx, [rcx+rdx]
; save bottom address of context stack as 'limit'
mov [rax+010h], rcx
; save address of context stack limit as 'dealloction stack'
mov [rax+08h], rcx
; compute address of transport_t
lea rcx, [rax+098h]
; store address of transport_t in hidden field
mov [rax+060h], rcx
; compute abs address of label finish
lea rcx, finish
; save address of finish as return-address for context-function
; will be entered after context-function returns
mov [rax+070h], rcx
ret ; return pointer to context-data
finish:
; exit code is zero
xor rcx, rcx
; exit application
call _exit
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)
*/
/****************************************************************************************
* *
* ---------------------------------------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ---------------------------------------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
* ---------------------------------------------------------------------------------- *
* | R12 | R13 | R14 | R15 | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ---------------------------------------------------------------------------------- *
* | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
* ---------------------------------------------------------------------------------- *
* | RBX | RBP | RIP | EXIT | *
* ---------------------------------------------------------------------------------- *
* *
****************************************************************************************/
.text
.globl make_fcontext
.type make_fcontext,@function
.align 16
make_fcontext:
/* first arg of make_fcontext() == top of context-stack */
movq %rdi, %rax
/* shift address in RAX to lower 16 byte boundary */
andq $-16, %rax
/* reserve space for context-data on context-stack */
/* on context-function entry: (RSP -0x8) % 16 == 0 */
leaq -0x40(%rax), %rax
/* third arg of make_fcontext() == address of context-function */
movq %rdx, 0x30(%rax)
/* compute abs address of label finish */
leaq finish(%rip), %rcx
/* save address of finish as return-address for context-function */
/* will be entered after context-function returns */
movq %rcx, 0x38(%rax)
ret /* return pointer to context-data */
finish:
/* exit code is zero */
xorq %rdi, %rdi
/* exit application */
call _exit@PLT
hlt
.size make_fcontext,.-make_fcontext
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits
/*
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 | 6 | 7 | *
* ---------------------------------------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
* ---------------------------------------------------------------------------------- *
* | R12 | R13 | R14 | R15 | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ---------------------------------------------------------------------------------- *
* | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
* ---------------------------------------------------------------------------------- *
* | RBX | RBP | RIP | EXIT | *
* ---------------------------------------------------------------------------------- *
* *
****************************************************************************************/
.text
.globl _make_fcontext
.align 8
_make_fcontext:
/* first arg of make_fcontext() == top of context-stack */
movq %rdi, %rax
/* shift address in RAX to lower 16 byte boundary */
movabs $-16, %r8
andq %r8, %rax
/* reserve space for context-data on context-stack */
/* on context-function entry: (RSP -0x8) % 16 == 0 */
leaq -0x40(%rax), %rax
/* third arg of make_fcontext() == address of context-function */
movq %rdx, 0x30(%rax)
/* compute abs address of label finish */
leaq finish(%rip), %rcx
/* save address of finish as return-address for context-function */
/* will be entered after context-function returns */
movq %rcx, 0x38(%rax)
ret /* return pointer to context-data */
finish:
/* exit code is zero */
xorq %rdi, %rdi
/* exit application */
call __exit
hlt
/*
Copyright Edward Nevill + Oliver Kowalke 2015
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 | 6 | 7 | *
* ------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
* ------------------------------------------------- *
* | x19 | x20 | x21 | x22 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
* ------------------------------------------------- *
* | x23 | x24 | x25 | x26 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
* ------------------------------------------------- *
* | x27 | x28 | FP | LR | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
* ------------------------------------------------- *
* | PC | align | | | *
* ------------------------------------------------- *
* *
*******************************************************/
.cpu generic+fp+simd
.text
.align 2
.global ontop_fcontext
.type ontop_fcontext, %function
ontop_fcontext:
# prepare stack for GP + FPU
sub sp, sp, #0x70
# save x19-x30
stp x19, x20, [sp, #0x00]
stp x21, x22, [sp, #0x10]
stp x23, x24, [sp, #0x20]
stp x25, x26, [sp, #0x30]
stp x27, x28, [sp, #0x40]
stp x29, x30, [sp, #0x50]
# save LR as PC
str x30, [sp, #0x60]
# store RSP (pointing to context-data) in X5
mov x4, sp
# restore RSP (pointing to context-data) from X1
mov sp, x0
# load x19-x30
ldp x19, x20, [sp, #0x00]
ldp x21, x22, [sp, #0x10]
ldp x23, x24, [sp, #0x20]
ldp x25, x26, [sp, #0x30]
ldp x27, x28, [sp, #0x40]
ldp x29, x30, [sp, #0x50]
# return transfer_t from jump
# pass transfer_t as first arg in context function
# X0 == FCTX, X1 == DATA
mov x0, x4
# skip pc
# restore stack from GP + FPU
add sp, sp, #0x70
# jump to ontop-function
ret x2
.size ontop_fcontext,.-ontop_fcontext
# Mark that we don't need executable stack.
.section .note.GNU-stack,"",%progbits
/*
Copyright Edward Nevill + Oliver Kowalke 2015
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 | 6 | 7 | *
* ------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
* ------------------------------------------------- *
* | x19 | x20 | x21 | x22 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
* ------------------------------------------------- *
* | x23 | x24 | x25 | x26 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
* ------------------------------------------------- *
* | x27 | x28 | FP | LR | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
* ------------------------------------------------- *
* | PC | align | | | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.global _ontop_fcontext
.balign 16
_ontop_fcontext:
# prepare stack for GP + FPU
sub sp, sp, #0x70
# save x19-x30
stp x19, x20, [sp, #0x00]
stp x21, x22, [sp, #0x10]
stp x23, x24, [sp, #0x20]
stp x25, x26, [sp, #0x30]
stp x27, x28, [sp, #0x40]
stp x29, x30, [sp, #0x50]
# save LR as PC
str x30, [sp, #0x60]
# store RSP (pointing to context-data) in X5
mov x4, sp
# restore RSP (pointing to context-data) from X1
mov sp, x0
# load x19-x30
ldp x19, x20, [sp, #0x00]
ldp x21, x22, [sp, #0x10]
ldp x23, x24, [sp, #0x20]
ldp x25, x26, [sp, #0x30]
ldp x27, x28, [sp, #0x40]
ldp x29, x30, [sp, #0x50]
# return transfer_t from jump
# pass transfer_t as first arg in context function
# X0 == FCTX, X1 == DATA
mov x0, x4
# skip pc
# restore stack from GP + FPU
add sp, sp, #0x70
# jump to ontop-function
ret x2
/*
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 | 6 | 7 | *
* ------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
* ------------------------------------------------- *
* |hiddn| v1 | v2 | v3 | v4 | v5 | v6 | v7 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
* ------------------------------------------------- *
* | v8 | lr | pc | FCTX| DATA| | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.globl ontop_fcontext
.align 2
.type ontop_fcontext,%function
ontop_fcontext:
@ save LR as PC
push {lr}
@ save hidden,V1-V8,LR
push {a1,v1-v8,lr}
@ store RSP (pointing to context-data) in A1
mov a1, sp
@ restore RSP (pointing to context-data) from A2
mov sp, a2
@ store parent context in A2
mov a2, a1
@ restore hidden,V1-V8,LR
pop {a1,v1-v8,lr}
@ return transfer_t from jump
str a2, [a1, #0]
str a3, [a1, #4]
@ pass transfer_t as first arg in context function
@ A1 == hidden, A2 == FCTX, A3 == DATA
@ skip PC
add sp, sp, #4
@ jump to ontop-function
bx a4
.size ontop_fcontext,.-ontop_fcontext
@ Mark that we don't need executable stack.
.section .note.GNU-stack,"",%progbits
/*
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 | 6 | 7 | *
* ------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
* ------------------------------------------------- *
* | sjlj|hiddn| v1 | v2 | v3 | v4 | v5 | v6 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
* ------------------------------------------------- *
* | v7 | v8 | lr | pc | FCTX| DATA| | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.globl _ontop_fcontext
.align 2
_ontop_fcontext:
@ save LR as PC
push {lr}
@ save hidden,V1-V8,LR
push {a1,v1-v8,lr}
@ locate TLS to save/restore SjLj handler
mrc p15, 0, v2, c13, c0, #3
bic v2, v2, #3
@ load TLS[__PTK_LIBC_DYLD_Unwind_SjLj_Key]
ldr v1, [v2, #8]
@ save SjLj handler
push {v1}
@ store RSP (pointing to context-data) in A1
mov a1, sp
@ restore RSP (pointing to context-data) from A2
mov sp, a2
@ restore SjLj handler
pop {v1}
@ store SjLj handler in TLS
str v1, [v2, #8]
@ store parent context in A2
mov a2, a1
@ restore hidden,V1-V8,LR
pop {a1,v1-v8,lr}
@ return transfer_t from jump
str a2, [a1, #0]
str a3, [a1, #4]
@ pass transfer_t as first arg in context function
@ A1 == hidden, A2 == FCTX, A3 == DATA
@ skip PC
add sp, sp, #4
@ jump to ontop-function
bx a4
;/*
; 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 | 6 | 7 | *
; * ------------------------------------------------- *
; * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
; * ------------------------------------------------- *
; * |deall|limit| base|hiddn| v1 | v2 | v3 | v4 | *
; * ------------------------------------------------- *
; * ------------------------------------------------- *
; * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
; * ------------------------------------------------- *
; * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
; * ------------------------------------------------- *
; * | v5 | v6 | v7 | v8 | lr | pc | FCTX| DATA| *
; * ------------------------------------------------- *
; * *
; *******************************************************
AREA |.text|, CODE
ALIGN 4
EXPORT ontop_fcontext
ontop_fcontext PROC
; save LR as PC
push {lr}
; save hidden,V1-V8,LR
push {a1,v1-v8,lr}
; load TIB to save/restore thread size and limit.
; we do not need preserve CPU flag and can use it's arg register
mrc p15, #0, v1, c13, c0, #2
; save current stack base
ldr a1, [v1, #0x04]
push {a1}
; save current stack limit
ldr a1, [v1, #0x08]
push {a1}
; save current deallocation stack
ldr a1, [v1, #0xe0c]
push {a1}
; store RSP (pointing to context-data) in A1
mov a1, sp
; restore RSP (pointing to context-data) from A2
mov sp, a2
; restore stack base
pop {a1}
str a1, [v1, #0x04]
; restore stack limit
pop {a1}
str a1, [v1, #0x08]
; restore deallocation stack
pop {a1}
str a1, [v1, #0xe0c]
; store parent context in A2
mov a2, a1
; restore hidden,V1-V8,LR
pop {a1,v1-v8,lr}
; return transfer_t from jump
str a2, [a1, #0]
str a3, [a1, #4]
; pass transfer_t as first arg in context function
; A1 == hidden, A2 == FCTX, A3 == DATA
; skip PC
add sp, sp, #4
; jump to ontop-function
bx a4
ENDP
END
/*
Copyright Sergue E. Leontiev 2013.
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)
*/
// Stub file for universal binary
#if defined(__arm__) || defined(__aarch64__) || defined(_M_ARM)
#if defined(__aarch64__)
#include "make_arm64_aapcs_macho_gas.S"
#else
#include "make_arm_aapcs_macho_gas.S"
#endif
#else
#if defined(__i386__)
#include "ontop_i386_sysv_macho_gas.S"
#elif defined(__x86_64__)
#include "ontop_x86_64_sysv_macho_gas.S"
#elif defined(__ppc__)
#include "ontop_ppc32_sysv_macho_gas.S"
#elif defined(__ppc64__)
#include "ontop_ppc64_sysv_macho_gas.S"
#else
#error "No arch's"
#endif
#endif
/*
Copyright Sergue E. Leontiev 2013.
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)
*/
// Stub file for universal binary
#if defined(__i386__)
#include "ontop_i386_sysv_macho_gas.S"
#elif defined(__x86_64__)
#include "ontop_x86_64_sysv_macho_gas.S"
#elif defined(__ppc__)
#include "ontop_ppc32_sysv_macho_gas.S"
#elif defined(__ppc64__)
#include "ontop_ppc64_sysv_macho_gas.S"
#else
#error "No arch's"
#endif
/*
Copyright Oliver Kowalke 2009.
Copyright Thomas Sailer 2013.
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 | 6 | 7 | *
* --------------------------------------------------------------------------------- *
* | 0h | 04h | 08h | 0ch | 010h | 014h | 018h | 01ch | *
* --------------------------------------------------------------------------------- *
* | fc_strg |fc_deallo| limit | base | fc_seh | EDI | ESI | EBX | *
* --------------------------------------------------------------------------------- *
* --------------------------------------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* --------------------------------------------------------------------------------- *
* | 020h | 024h | 028h | 02ch | 030h | 034h | 038h | 03ch | *
* --------------------------------------------------------------------------------- *
* | EBP | EIP | to | data | | EH NXT |SEH HNDLR| | *
* --------------------------------------------------------------------------------- *
*************************************************************************************/
.file "ontop_i386_ms_pe_gas.asm"
.text
.p2align 4,,15
.globl _ontop_fcontext
.def _ontop_fcontext; .scl 2; .type 32; .endef
_ontop_fcontext:
pushl %ebp /* save EBP */
pushl %ebx /* save EBX */
pushl %esi /* save ESI */
pushl %edi /* save EDI */
/* load NT_TIB */
movl %fs:(0x18), %edx
/* load current SEH exception list */
movl (%edx), %eax
push %eax
/* load current stack base */
movl 0x04(%edx), %eax
push %eax
/* load current stack limit */
movl 0x08(%edx), %eax
push %eax
/* load current dealloction stack */
movl 0xe0c(%edx), %eax
push %eax
/* load fiber local storage */
movl 0x10(%edx), %eax
push %eax
/* store ESP (pointing to context-data) in EAX */
movl %esp, %ecx
/* first arg of ontop_fcontext() == fcontext to jump to */
movl 0x28(%esp), %eax
/* pass parent fcontext_t */
movl %ecx, 0x28(%eax)
/* second arg of ontop_fcontext() == data to be transferred */
movl 0x2c(%esp), %ecx
/* pass data */
movl %ecx, 0x2c(%eax)
/* third arg of ontop_fcontext() == ontop-function */
movl 0x30(%esp), %ecx
/* restore ESP (pointing to context-data) from EDX */
movl %eax, %esp
/* load NT_TIB into ECX */
movl %fs:(0x18), %edx
/* restore fiber local storage */
popl %eax
movl %eax, 0x10(%edx)
/* restore current deallocation stack */
popl %eax
movl %eax, 0xe0c(%edx)
/* restore current stack limit */
popl %eax
movl %eax, 0x08(%edx)
/* restore current stack base */
popl %eax
movl %eax, 0x04(%edx)
/* restore current SEH exception list */
popl %eax
movl %eax, (%edx)
popl %edi /* save EDI */
popl %esi /* save ESI */
popl %ebx /* save EBX */
popl %ebp /* save EBP */
/* jump to context */
jmp *%ecx
.section .drectve
.ascii " -export:\"ontop_fcontext\""
; 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 | 6 | 7 |
; ---------------------------------------------------------------------------------
; | 0h | 04h | 08h | 0ch | 010h | 014h | 018h | 01ch |
; ---------------------------------------------------------------------------------
; | fc_strg |fc_deallo| limit | base | fc_seh | EDI | ESI | EBX |
; ---------------------------------------------------------------------------------
; ---------------------------------------------------------------------------------
; | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
; ---------------------------------------------------------------------------------
; | 020h | 024h | 028h | 02ch | 030h | 034h | 038h | 03ch |
; ---------------------------------------------------------------------------------
; | EBP | EIP | to | data | | EH NXT |SEH HNDLR| |
; ---------------------------------------------------------------------------------
.386
.XMM
.model flat, c
.code
ontop_fcontext PROC BOOST_CONTEXT_EXPORT
push ebp ; save EBP
push ebx ; save EBX
push esi ; save ESI
push edi ; save EDI
assume fs:nothing
; load NT_TIB into EDX
mov edx, fs:[018h]
assume fs:error
; load current SEH exception list
mov eax, [edx]
push eax
; load current stack base
mov eax, [edx+04h]
push eax
; load current stack limit
mov eax, [edx+08h]
push eax
; load current deallocation stack
mov eax, [edx+0e0ch]
push eax
; load fiber local storage
mov eax, [edx+010h]
push eax
; store ESP (pointing to context-data) in ECX
mov ecx, esp
; first arg of ontop_fcontext() == fcontext to jump to
mov eax, [esp+028h]
; pass parent fcontext_t
mov [eax+028h], ecx
; second arg of ontop_fcontext() == data to be transferred
mov ecx, [esp+02ch]
; pass data
mov [eax+02ch], ecx
; third arg of ontop_fcontext() == ontop-function
mov ecx, [esp+030h]
; restore ESP (pointing to context-data) from EAX
mov esp, eax
assume fs:nothing
; load NT_TIB into EDX
mov edx, fs:[018h]
assume fs:error
; restore fiber local storage
pop eax
mov [edx+010h], eax
; restore current deallocation stack
pop eax
mov [edx+0e0ch], eax
; restore current stack limit
pop eax
mov [edx+08h], eax
; restore current stack base
pop eax
mov [edx+04h], eax
; restore current SEH exception list
pop eax
mov [edx], eax
pop edi ; save EDI
pop esi ; save ESI
pop ebx ; save EBX
pop ebp ; save EBP
; jump to context
jmp ecx
ontop_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)
*/
/*****************************************************************************************
* *
* ----------------------------------------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ----------------------------------------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
* ----------------------------------------------------------------------------------- *
* | EDI | ESI | EBX | EBP | EIP | hidden | to | data | *
* ----------------------------------------------------------------------------------- *
* *
*****************************************************************************************/
.text
.globl ontop_fcontext
.align 2
.type ontop_fcontext,@function
ontop_fcontext:
pushl %ebp /* save EBP */
pushl %ebx /* save EBX */
pushl %esi /* save ESI */
pushl %edi /* save EDI */
/* store fcontext_t in ECX */
movl %esp, %ecx
/* first arg of ontop_fcontext() == fcontext to jump to */
movl 0x18(%esp), %eax
/* pass parent fcontext_t */
movl %ecx, 0x18(%eax)
/* second arg of ontop_fcontext() == data to be transferred */
movl 0x1c(%esp), %ecx
/* pass data */
movl %ecx, 0x1c(%eax)
/* third arg of ontop_fcontext() == ontop-function */
movl 0x20(%esp), %ecx
/* restore ESP (pointing to context-data) from EDX */
movl %eax, %esp
popl %edi /* restore EDI */
popl %esi /* restore ESI */
popl %ebx /* restore EBX */
popl %ebp /* restore EBP */
/* jump to context */
jmp *%ecx
.size ontop_fcontext,.-ontop_fcontext
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits
/*
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 | 6 | 7 | *
* ----------------------------------------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
* ----------------------------------------------------------------------------------- *
* | EDI | ESI | EBX | EBP | EIP | hidden | to | data | *
* ----------------------------------------------------------------------------------- *
* *
*****************************************************************************************/
.text
.globl _ontop_fcontext
.align 2
_ontop_fcontext:
pushl %ebp /* save EBP */
pushl %ebx /* save EBX */
pushl %esi /* save ESI */
pushl %edi /* save EDI */
/* store fcontext_t in ECX */
movl %esp, %ecx
/* first arg of ontop_fcontext() == fcontext to jump to */
movl 0x18(%esp), %eax
/* pass parent fcontext_t */
movl %ecx, 0x18(%eax)
/* second arg of ontop_fcontext() == data to be transferred */
movl 0x1c(%esp), %ecx
/* pass data */
movl %ecx, 0x1c(%eax)
/* third arg of ontop_fcontext() == ontop-function */
movl 0x20(%esp), %ecx
/* restore ESP (pointing to context-data) from EDX */
movl %eax, %esp
popl %edi /* restore EDI */
popl %esi /* restore ESI */
popl %ebx /* restore EBX */
popl %ebp /* restore EBP */
/* jump to context */
jmp *%ecx
/*
Copyright Sergue E. Leontiev 2013.
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)
*/
// Stub file for universal binary
#if defined(__i386__)
#include "ontop_i386_sysv_macho_gas.S"
#elif defined(__x86_64__)
#include "ontop_x86_64_sysv_macho_gas.S"
#else
#error "No arch's"
#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)
*/
/*******************************************************
* *
* ------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* | S0 | S1 | S2 | S3 | S4 | S5 | S6 | S7 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | FP |hiddn| RA | PC | GP | FCTX| DATA| | *
* ------------------------------------------------- *
* *
* *****************************************************/
.text
.globl ontop_fcontext
.align 2
.type ontop_fcontext,@function
.ent ontop_fcontext
ontop_fcontext:
# reserve space on stack
addiu $sp, $sp, -112
sw $s0, ($sp) # save S0
sw $s1, 4($sp) # save S1
sw $s2, 8($sp) # save S2
sw $s3, 12($sp) # save S3
sw $s4, 16($sp) # save S4
sw $s5, 20($sp) # save S5
sw $s6, 24($sp) # save S6
sw $s7, 28($sp) # save S7
sw $fp, 32($sp) # save FP
sw $a0, 36($sp) # save hidden, address of returned transfer_t
sw $ra, 40($sp) # save RA
sw $ra, 44($sp) # save RA as PC
# store SP (pointing to context-data) in A0
move $a0, $sp
# restore SP (pointing to context-data) from A1
move $sp, $a1
lw $s0, ($sp) # restore S0
lw $s1, 4($sp) # restore S1
lw $s2, 8($sp) # restore S2
lw $s3, 12($sp) # restore S3
lw $s4, 16($sp) # restore S4
lw $s5, 20($sp) # restore S5
lw $s6, 24($sp) # restore S6
lw $s7, 28($sp) # restore S7
lw $fp, 32($sp) # restore FP
lw $t0, 36($sp) # restore hidden, address of returned transfer_t
lw $ra, 40($sp) # restore RA
# load PC
lw $t9, 44($sp)
# adjust stack
addiu $sp, $sp, 112
# return transfer_t from jump
sw $a0, ($t0) # fctx of transfer_t
sw $a2, 4($t0) # data of transfer_t
# pass transfer_t as first arg in context function
# A0 == hidden, A1 == fctx, A2 == data
move $a1, $a0
move $a0, $t0
# jump to context
jr $a3
.end ontop_fcontext
.size ontop_fcontext, .-ontop_fcontext
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits
/*
Copyright Sergue E. Leontiev 2013.
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)
*/
// Stub file for universal binary
#if defined(__ppc__)
#include "ontop_ppc32_sysv_macho_gas.S"
#elif defined(__ppc64__)
#include "ontop_ppc64_sysv_macho_gas.S"
#else
#error "No arch's"
#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)
*/
/*******************************************************
* *
* ------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* | R13 | R14 | R15 | R16 | R17 | R18 | R19 | R20 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | R21 | R22 | R23 | R24 | R25 | R26 | R27 | R28 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
* ------------------------------------------------- *
* | R29 | R30 | R31 |hiddn| CR | LR | PC | FCTX| *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
* ------------------------------------------------- *
* | DATA| | | | | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.globl ontop_fcontext
.align 2
.type ontop_fcontext,@function
ontop_fcontext:
# reserve space on stack
subi %r1, %r1, 92
stw %r13, 0(%r1) # save R13
stw %r14, 4(%r1) # save R14
stw %r15, 8(%r1) # save R15
stw %r16, 12(%r1) # save R16
stw %r17, 16(%r1) # save R17
stw %r18, 20(%r1) # save R18
stw %r19, 24(%r1) # save R19
stw %r20, 28(%r1) # save R20
stw %r21, 32(%r1) # save R21
stw %r22, 36(%r1) # save R22
stw %r23, 40(%r1) # save R23
stw %r24, 44(%r1) # save R24
stw %r25, 48(%r1) # save R25
stw %r26, 52(%r1) # save R26
stw %r27, 56(%r1) # save R27
stw %r28, 60(%r1) # save R28
stw %r29, 64(%r1) # save R29
stw %r30, 68(%r1) # save R30
stw %r31, 72(%r1) # save R31
stw %r3, 76(%r1) # save hidden
# save CR
mfcr %r0
stw %r0, 80(%r1)
# save LR
mflr %r0
stw %r0, 84(%r1)
# save LR as PC
stw %r0, 88(%r1)
# store RSP (pointing to context-data) in R7
mr %r7, %r1
# restore RSP (pointing to context-data) from R4
mr %r1, %r4
lwz %r13, 0(%r1) # restore R13
lwz %r14, 4(%r1) # restore R14
lwz %r15, 8(%r1) # restore R15
lwz %r16, 12(%r1) # restore R16
lwz %r17, 16(%r1) # restore R17
lwz %r18, 20(%r1) # restore R18
lwz %r19, 24(%r1) # restore R19
lwz %r20, 28(%r1) # restore R20
lwz %r21, 32(%r1) # restore R21
lwz %r22, 36(%r1) # restore R22
lwz %r23, 40(%r1) # restore R23
lwz %r24, 44(%r1) # restore R24
lwz %r25, 48(%r1) # restore R25
lwz %r26, 52(%r1) # restore R26
lwz %r27, 56(%r1) # restore R27
lwz %r28, 60(%r1) # restore R28
lwz %r29, 64(%r1) # restore R29
lwz %r30, 68(%r1) # restore R30
lwz %r31, 72(%r1) # restore R31
lwz %r4, 76(%r1) # restore hidden
# restore CR
lwz %r0, 80(%r1)
mtcr %r0
# restore LR
lwz %r0, 84(%r1)
mtlr %r0
# ignore PC
# adjust stack
addi %r1, %r1, 92
# return transfer_t
stw %r7, 0(%r4)
stw %r5, 4(%r4)
# restore CTR
mtctr %r6
# jump to ontop-function
bctr
.size ontop_fcontext, .-ontop_fcontext
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits
/*
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 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* | R13 | R14 | R15 | R16 | R17 | R18 | R19 | R20 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | R21 | R22 | R23 | R24 | R25 | R26 | R27 | R28 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
* ------------------------------------------------- *
* | R29 | R30 | R31 |hiddn| CR | LR | PC | FCTX| *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
* ------------------------------------------------- *
* | DATA| | | | | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.globl _ontop_fcontext
.align 2
_ontop_fcontext:
# reserve space on stack
subi r1, r1, 92
stw r13, 0(r1) # save R13
stw r14, 4(r1) # save R14
stw r15, 8(r1) # save R15
stw r16, 12(r1) # save R16
stw r17, 16(r1) # save R17
stw r18, 20(r1) # save R18
stw r19, 24(r1) # save R19
stw r20, 28(r1) # save R20
stw r21, 32(r1) # save R21
stw r22, 36(r1) # save R22
stw r23, 40(r1) # save R23
stw r24, 44(r1) # save R24
stw r25, 48(r1) # save R25
stw r26, 52(r1) # save R26
stw r27, 56(r1) # save R27
stw r28, 60(r1) # save R28
stw r29, 64(r1) # save R29
stw r30, 68(r1) # save R30
stw r31, 72(r1) # save R31
stw r3, 76(r1) # save hidden
# save CR
mfcr r0
stw r0, 80(r1)
# save LR
mflr r0
stw r0, 84(r1)
# save LR as PC
stw r0, 88(r1)
# store RSP (pointing to context-data) in R7
mr r7, r1
# restore RSP (pointing to context-data) from R4
mr r1, r4
lwz r13, 0(r1) # restore R13
lwz r14, 4(r1) # restore R14
lwz r15, 8(r1) # restore R15
lwz r16, 12(r1) # restore R16
lwz r17, 16(r1) # restore R17
lwz r18, 20(r1) # restore R18
lwz r19, 24(r1) # restore R19
lwz r20, 28(r1) # restore R20
lwz r21, 32(r1) # restore R21
lwz r22, 36(r1) # restore R22
lwz r23, 40(r1) # restore R23
lwz r24, 44(r1) # restore R24
lwz r25, 48(r1) # restore R25
lwz r26, 52(r1) # restore R26
lwz r27, 56(r1) # restore R27
lwz r28, 60(r1) # restore R28
lwz r29, 64(r1) # restore R29
lwz r30, 68(r1) # restore R30
lwz r31, 72(r1) # restore R31
lwz r4, 76(r1) # restore hidden
# restore CR
lwz r0, 80(r1)
mtcr r0
# restore LR
lwz r0, 84(r1)
mtlr r0
# ignore PC
# adjust stack
addi r1, r1, 92
# return transfer_t
stw r7, 0(r4)
stw r5, 4(r4)
# restore CTR
mtctr r6
# jump to ontop-function
bctr
.globl .ontop_fcontext
.globl ontop_fcontext[DS]
.align 2
.csect ontop_fcontext[DS]
ontop_fcontext:
.long .ontop_fcontext
.ontop_fcontext:
# reserve space on stack
subi 1, 1, 92
stw 13, 0(1) # save R13
stw 14, 4(1) # save R14
stw 15, 8(1) # save R15
stw 16, 12(1) # save R16
stw 17, 16(1) # save R17
stw 18, 20(1) # save R18
stw 19, 24(1) # save R19
stw 20, 28(1) # save R20
stw 21, 32(1) # save R21
stw 22, 36(1) # save R22
stw 23, 40(1) # save R23
stw 24, 44(1) # save R24
stw 25, 48(1) # save R25
stw 26, 52(1) # save R26
stw 27, 56(1) # save R27
stw 28, 60(1) # save R28
stw 29, 64(1) # save R29
stw 30, 68(1) # save R30
stw 31, 72(1) # save R31
stw 3, 76(1) # save hidden
# save CR
mfcr 0
stw 0, 80(1)
# save LR
mflr 0
stw 0, 84(1)
# save LR as PC
stw 0, 88(1)
# store RSP (pointing to context-data) in R6
mr 7, 1
# restore RSP (pointing to context-data) from R4
mr 1, 4
lwz 13, 0(1) # restore R13
lwz 14, 4(1) # restore R14
lwz 15, 8(1) # restore R15
lwz 16, 12(1) # restore R16
lwz 17, 16(1) # restore R17
lwz 18, 20(1) # restore R18
lwz 19, 24(1) # restore R19
lwz 20, 28(1) # restore R20
lwz 21, 32(1) # restore R21
lwz 22, 36(1) # restore R22
lwz 23, 40(1) # restore R23
lwz 24, 44(1) # restore R24
lwz 25, 48(1) # restore R25
lwz 26, 52(1) # restore R26
lwz 27, 56(1) # restore R27
lwz 28, 60(1) # restore R28
lwz 29, 64(1) # restore R29
lwz 30, 68(1) # restore R30
lwz 31, 72(1) # restore R31
lwz 4, 76(1) # restore hidden
# restore CR
lwz 0, 80(1)
mtcr 0
# restore LR
lwz 0, 84(1)
mtlr 0
# ignore PC
# adjust stack
addi 1, 1, 92
# return transfer_t
stw 7, 0(3)
stw 5, 4(3)
# restore CTR
mtctr 6
# jump to context
bctr
/*
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 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* | TOC | R14 | R15 | R16 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | R17 | R18 | R19 | R20 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
* ------------------------------------------------- *
* | R21 | R22 | R23 | R24 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
* ------------------------------------------------- *
* | R25 | R26 | R27 | R28 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
* ------------------------------------------------- *
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
* ------------------------------------------------- *
* | R29 | R30 | R31 | hidden | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
* ------------------------------------------------- *
* | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | *
* ------------------------------------------------- *
* | CR | LR | PC | back-chain| *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | *
* ------------------------------------------------- *
* | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | *
* ------------------------------------------------- *
* | cr saved | lr saved | compiler | linker | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | *
* ------------------------------------------------- *
* | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | *
* ------------------------------------------------- *
* | TOC saved | FCTX | DATA | | *
* ------------------------------------------------- *
* *
*******************************************************/
.globl ontop_fcontext
#if _CALL_ELF == 2
.text
.align 2
ontop_fcontext:
addis %r2, %r12, .TOC.-ontop_fcontext@ha
addi %r2, %r2, .TOC.-ontop_fcontext@l
.localentry ontop_fcontext, . - ontop_fcontext
#else
.section ".opd","aw"
.align 3
ontop_fcontext:
# ifdef _CALL_LINUX
.quad .L.ontop_fcontext,.TOC.@tocbase,0
.type ontop_fcontext,@function
.text
.align 2
.L.ontop_fcontext:
# else
.hidden .ontop_fcontext
.globl .ontop_fcontext
.quad .ontop_fcontext,.TOC.@tocbase,0
.size ontop_fcontext,24
.type .ontop_fcontext,@function
.text
.align 2
.ontop_fcontext:
# endif
#endif
# reserve space on stack
subi %r1, %r1, 184
#if _CALL_ELF != 2
std %r2, 0(%r1) # save TOC
#endif
std %r14, 8(%r1) # save R14
std %r15, 16(%r1) # save R15
std %r16, 24(%r1) # save R16
std %r17, 32(%r1) # save R17
std %r18, 40(%r1) # save R18
std %r19, 48(%r1) # save R19
std %r20, 56(%r1) # save R20
std %r21, 64(%r1) # save R21
std %r22, 72(%r1) # save R22
std %r23, 80(%r1) # save R23
std %r24, 88(%r1) # save R24
std %r25, 96(%r1) # save R25
std %r26, 104(%r1) # save R26
std %r27, 112(%r1) # save R27
std %r29, 120(%r1) # save R28
std %r29, 128(%r1) # save R29
std %r30, 136(%r1) # save R30
std %r31, 144(%r1) # save R31
std %r3, 152(%r1) # save hidden
# save CR
mfcr %r0
std %r0, 160(%r1)
# save LR
mflr %r0
std %r0, 168(%r1)
# save LR as PC
std %r0, 176(%r1)
# store RSP (pointing to context-data) in R7
mr %r7, %r1
# restore RSP (pointing to context-data) from R4
mr %r1, %r4
#if _CALL_ELF != 2
ld %r2, 0(%r1) # restore TOC
#endif
ld %r14, 8(%r1) # restore R14
ld %r15, 16(%r1) # restore R15
ld %r16, 24(%r1) # restore R16
ld %r17, 32(%r1) # restore R17
ld %r18, 40(%r1) # restore R18
ld %r19, 48(%r1) # restore R19
ld %r20, 56(%r1) # restore R20
ld %r21, 64(%r1) # restore R21
ld %r22, 72(%r1) # restore R22
ld %r23, 80(%r1) # restore R23
ld %r24, 88(%r1) # restore R24
ld %r25, 96(%r1) # restore R25
ld %r26, 104(%r1) # restore R26
ld %r27, 112(%r1) # restore R27
ld %r28, 120(%r1) # restore R28
ld %r29, 128(%r1) # restore R29
ld %r30, 136(%r1) # restore R30
ld %r31, 144(%r1) # restore R31
ld %r4, 152(%r1) # restore hidden
# restore CR
ld %r0, 160(%r1)
mtcr %r0
# restore LR
ld %r0, 168(%r1)
mtlr %r0
# ignore PC
# adjust stack
addi %r1, %r1, 184
# return transfer_t
std %r7, 0(%r4)
std %r5, 8(%r4)
# restore CTR
mtctr %r6
# jump to context
bctr
#if _CALL_ELF == 2
.size ontop_fcontext, .-ontop_fcontext
#else
# ifdef _CALL_LINUX
.size .ontop_fcontext, .-.L.ontop_fcontext
# else
.size .ontop_fcontext, .-.ontop_fcontext
# endif
#endif
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits
/*
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 | 6 | 7 | *
* ------------------------------------------------- *
* | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | *
* ------------------------------------------------- *
* | TOC | R14 | R15 | R16 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ------------------------------------------------- *
* | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | *
* ------------------------------------------------- *
* | R17 | R18 | R19 | R20 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ------------------------------------------------- *
* | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | *
* ------------------------------------------------- *
* | R21 | R22 | R23 | R24 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ------------------------------------------------- *
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
* ------------------------------------------------- *
* | R25 | R26 | R27 | R28 | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
* ------------------------------------------------- *
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
* ------------------------------------------------- *
* | R29 | R30 | R31 | hidden | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
* ------------------------------------------------- *
* | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | *
* ------------------------------------------------- *
* | CR | LR | PC | back-chain| *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | *
* ------------------------------------------------- *
* | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | *
* ------------------------------------------------- *
* | cr saved | lr saved | compiler | linker | *
* ------------------------------------------------- *
* ------------------------------------------------- *
* | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | *
* ------------------------------------------------- *
* | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | *
* ------------------------------------------------- *
* | TOC saved | FCTX | DATA | | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.align 2
.globl ontop_fcontext
_ontop_fcontext:
; reserve space on stack
subi r1, r1, 184
std %r14, 8(%r1) ; save R14
std %r15, 16(%r1) ; save R15
std %r16, 24(%r1) ; save R16
std %r17, 32(%r1) ; save R17
std %r18, 40(%r1) ; save R18
std %r19, 48(%r1) ; save R19
std %r20, 56(%r1) ; save R20
std %r21, 64(%r1) ; save R21
std %r22, 72(%r1) ; save R22
std %r23, 80(%r1) ; save R23
std %r24, 88(%r1) ; save R24
std %r25, 96(%r1) ; save R25
std %r26, 104(%r1) ; save R26
std %r27, 112(%r1) ; save R27
std %r29, 120(%r1) ; save R28
std %r29, 128(%r1) ; save R29
std %r30, 136(%r1) ; save R30
std %r31, 144(%r1) ; save R31
std %r3, 152(%r1) ; save hidden
; save CR
mfcr r0
std r0, 160(r1)
; save LR
mflr r0
std r0, 168(r1)
; save LR as PC
std r0, 176(r1)
; store RSP (pointing to context-data) in R7
mr %r7, %r1
; restore RSP (pointing to context-data) from R4
mr r1, r4
ld %r14, 8(%r1) ; restore R14
ld %r15, 16(%r1) ; restore R15
ld %r16, 24(%r1) ; restore R16
ld %r17, 32(%r1) ; restore R17
ld %r18, 40(%r1) ; restore R18
ld %r19, 48(%r1) ; restore R19
ld %r20, 56(%r1) ; restore R20
ld %r21, 64(%r1) ; restore R21
ld %r22, 72(%r1) ; restore R22
ld %r23, 80(%r1) ; restore R23
ld %r24, 88(%r1) ; restore R24
ld %r25, 96(%r1) ; restore R25
ld %r26, 104(%r1) ; restore R26
ld %r27, 112(%r1) ; restore R27
ld %r28, 120(%r1) ; restore R28
ld %r29, 128(%r1) ; restore R29
ld %r30, 136(%r1) ; restore R30
ld %r31, 144(%r1) ; restore R31
ld %r4, 152(%r1) ; restore hidden
; restore CR
ld r0, 160(r1)
mtcr r0
; restore LR
ld r0, 168(r1)
mtlr r0
; ignore PC
; adjust stack
addi r1, r1, 184
; return transfer_t
std %r7, 0(%r4)
std %r5, 8(%r4)
; restore CTR
mtctr r6
; jump to context
bctr
.align 2
.globl .jump_fcontext
.jump_fcontext:
# reserve space on stack
subi 1, 1, 184
std 13, 0(1) # save R13
std 14, 8(1) # save R14
std 15, 16(1) # save R15
std 16, 24(1) # save R16
std 17, 32(1) # save R17
std 18, 40(1) # save R18
std 19, 48(1) # save R19
std 20, 56(1) # save R20
std 21, 64(1) # save R21
std 22, 72(1) # save R22
std 23, 80(1) # save R23
std 24, 88(1) # save R24
std 25, 96(1) # save R25
std 26, 104(1) # save R26
std 27, 112(1) # save R27
std 29, 120(1) # save R28
std 29, 128(1) # save R29
std 30, 136(1) # save R30
std 31, 144(1) # save R31
std 3, 152(1) # save hidden
# save CR
mfcr 0
std 0, 160(1)
# save LR
mflr 0
std 0, 168(1)
# save LR as PC
std 0, 176(1)
# store RSP (pointing to context-data) in R7
mr 7, 1
# restore RSP (pointing to context-data) from R4
mr 1, 4
ld 13, 0(1) # restore R13
ld 14, 8(1) # restore R14
ld 15, 16(1) # restore R15
ld 16, 24(1) # restore R16
ld 17, 32(1) # restore R17
ld 18, 40(1) # restore R18
ld 19, 48(1) # restore R19
ld 20, 56(1) # restore R20
ld 21, 64(1) # restore R21
ld 22, 72(1) # restore R22
ld 23, 80(1) # restore R23
ld 24, 88(1) # restore R24
ld 25, 96(1) # restore R25
ld 26, 104(1) # restore R26
ld 27, 112(1) # restore R27
ld 28, 120(1) # restore R28
ld 29, 128(1) # restore R29
ld 30, 136(1) # restore R30
ld 31, 144(1) # restore R31
ld 4, 152(1) # restore hidden
# restore CR
ld 0, 160(1)
mtcr 0
# restore LR
ld 0, 168(1)
mtlr 0
# ignore PC
# adjust stack
addi 1, 1, 184
# return transfer_t
std 7, 0(4)
std 5, 8(4)
# restore CTR
mtctr 6
# jump to context
bctr
/*
Copyright Oliver Kowalke 2009.
Copyright Thomas Sailer 2013.
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 | 6 | 7 | *
* ---------------------------------------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
* ---------------------------------------------------------------------------------- *
* | fbr_strg | fc_dealloc | limit | base | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ---------------------------------------------------------------------------------- *
* | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
* ---------------------------------------------------------------------------------- *
* | R12 | R13 | R14 | R15 | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
* ---------------------------------------------------------------------------------- *
* | 0xe40 | 0x44 | 0x48 | 0x4c | 0x50 | 0x54 | 0x58 | 0x5c | *
* ---------------------------------------------------------------------------------- *
* | RDI | RSI | RBX | RBP | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
* ---------------------------------------------------------------------------------- *
* | 0x60 | 0x64 | 0x68 | 0x6c | 0x70 | 0x74 | 0x78 | 0x7c | *
* ---------------------------------------------------------------------------------- *
* | hidden | RIP | EXIT | parameter area | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 32 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | *
* ---------------------------------------------------------------------------------- *
* | 0x80 | 0x84 | 0x88 | 0x8c | 0x90 | 0x94 | 0x98 | 0x9c | *
* ---------------------------------------------------------------------------------- *
* | parameter area | FCTX | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | *
* ---------------------------------------------------------------------------------- *
* | 0xa0 | 0xa4 | 0xa8 | 0xac | 0xb0 | 0xb4 | 0xb8 | 0xbc | *
* ---------------------------------------------------------------------------------- *
* | DATA | | | | *
* ---------------------------------------------------------------------------------- *
* *
* ***********************************************************************************/
.file "ontop_x86_64_ms_pe_gas.asm"
.text
.p2align 4,,15
.globl ontop_fcontext
.def ontop_fcontext; .scl 2; .type 32; .endef
.seh_proc ontop_fcontext
ontop_fcontext:
.seh_endprologue
pushq %rcx /* save hidden address of transport_t */
pushq %rbp /* save RBP */
pushq %rbx /* save RBX */
pushq %rsi /* save RSI */
pushq %rdi /* save RDI */
pushq %r15 /* save R15 */
pushq %r14 /* save R14 */
pushq %r13 /* save R13 */
pushq %r12 /* save R12 */
/* load NT_TIB */
movq %gs:(0x30), %r10
/* save current stack base */
movq 0x08(%r10), %rax
pushq %rax
/* save current stack limit */
movq 0x10(%r10), %rax
pushq %rax
/* save current deallocation stack */
movq 0x1478(%r10), %rax
pushq %rax
/* save fiber local storage */
movq 0x18(%r10), %rax
pushq %rax
/* preserve RSP (pointing to context-data) in RCX */
movq %rsp, %rcx
/* restore RSP (pointing to context-data) from RDX */
movq %rdx, %rsp
/* load NT_TIB */
movq %gs:(0x30), %r10
/* restore fiber local storage */
popq %rax
movq %rax, 0x18(%r10)
/* restore deallocation stack */
popq %rax
movq %rax, 0x1478(%r10)
/* restore stack limit */
popq %rax
movq %rax, 0x10(%r10)
/* restore stack base */
popq %rax
movq %rax, 0x8(%r10)
popq %r12 /* restore R12 */
popq %r13 /* restore R13 */
popq %r14 /* restore R14 */
popq %r15 /* restore R15 */
popq %rdi /* restore RDI */
popq %rsi /* restore RSI */
popq %rbx /* restore RBX */
popq %rbp /* restore RBP */
popq %rax /* restore hidden address of transport_t */
/* keep return-address on stack */
/* transport_t returned in RAX */
/* return parent fcontext_t */
movq %rcx, (%rax)
/* return data */
movq %r8, 0x8(%rax)
/* transport_t as 1.arg of context-function */
/* RCX contains address of returned (hidden) transfer_t */
movq %rax, %rcx
/* RDX contains address of passed transfer_t */
movq %rax, %rdx
/* indirect jump to context */
jmp *%r9
.seh_endproc
.section .drectve
.ascii " -export:\"ontop_fcontext\""
; 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 | 6 | 7 |
; ----------------------------------------------------------------------------------
; | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c |
; ----------------------------------------------------------------------------------
; | fbr_strg | fc_dealloc | limit | base |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
; ----------------------------------------------------------------------------------
; | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c |
; ----------------------------------------------------------------------------------
; | R12 | R13 | R14 | R15 |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
; ----------------------------------------------------------------------------------
; | 0xe40 | 0x44 | 0x48 | 0x4c | 0x50 | 0x54 | 0x58 | 0x5c |
; ----------------------------------------------------------------------------------
; | RDI | RSI | RBX | RBP |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
; ----------------------------------------------------------------------------------
; | 0x60 | 0x64 | 0x68 | 0x6c | 0x70 | 0x74 | 0x78 | 0x7c |
; ----------------------------------------------------------------------------------
; | hidden | RIP | EXIT | parameter area |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 32 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
; ----------------------------------------------------------------------------------
; | 0x80 | 0x84 | 0x88 | 0x8c | 0x90 | 0x94 | 0x98 | 0x9c |
; ----------------------------------------------------------------------------------
; | parameter area | FCTX |
; ----------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------
; | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |
; ----------------------------------------------------------------------------------
; | 0xa0 | 0xa4 | 0xa8 | 0xac | 0xb0 | 0xb4 | 0xb8 | 0xbc |
; ----------------------------------------------------------------------------------
; | DATA | | | |
; ----------------------------------------------------------------------------------
.code
ontop_fcontext PROC BOOST_CONTEXT_EXPORT FRAME
.endprolog
push rcx ; save hidden address of transport_t
push rbp ; save RBP
push rbx ; save RBX
push rsi ; save RSI
push rdi ; save RDI
push r15 ; save R15
push r14 ; save R14
push r13 ; save R13
push r12 ; save R12
; load NT_TIB
mov r10, gs:[030h]
; save current stack base
mov rax, [r10+08h]
push rax
; save current stack limit
mov rax, [r10+010h]
push rax
; save current deallocation stack
mov rax, [r10+01478h]
push rax
; save fiber local storage
mov rax, [r10+018h]
push rax
; preserve RSP (pointing to context-data) in RCX
mov rcx, rsp
; restore RSP (pointing to context-data) from RDX
mov rsp, rdx
; load NT_TIB
mov r10, gs:[030h]
; restore fiber local storage
pop rax
mov [r10+018h], rax
; restore deallocation stack
pop rax
mov [r10+01478h], rax
; restore stack limit
pop rax
mov [r10+010h], rax
; restore stack base
pop rax
mov [r10+08h], rax
pop r12 ; restore R12
pop r13 ; restore R13
pop r14 ; restore R14
pop r15 ; restore R15
pop rdi ; restore RDI
pop rsi ; restore RSI
pop rbx ; restore RBX
pop rbp ; restore RBP
pop rax ; restore hidden address of transport_t
; keep return-address on stack
; transport_t returned in RAX
; return parent fcontext_t
mov [rax], rcx
; return data
mov [rax+08h], r8
; transport_t as 1.arg of context-function
; RCX contains address of returned (hidden) transfer_t
mov rcx, rax
; RDX contains address of passed transfer_t
mov rdx, rax
; indirect jump to context
jmp r9
ontop_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)
*/
/****************************************************************************************
* *
* ---------------------------------------------------------------------------------- *
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
* ---------------------------------------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
* ---------------------------------------------------------------------------------- *
* | R12 | R13 | R14 | R15 | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ---------------------------------------------------------------------------------- *
* | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
* ---------------------------------------------------------------------------------- *
* | RBX | RBP | RIP | EXIT | *
* ---------------------------------------------------------------------------------- *
* *
****************************************************************************************/
.text
.globl ontop_fcontext
.type ontop_fcontext,@function
.align 16
ontop_fcontext:
pushq %rbp /* save RBP */
pushq %rbx /* save RBX */
pushq %r15 /* save R15 */
pushq %r14 /* save R14 */
pushq %r13 /* save R13 */
pushq %r12 /* save R12 */
/* store RSP (pointing to context-data) in RAX */
movq %rsp, %rax
/* restore RSP (pointing to context-data) from RDI */
movq %rdi, %rsp
popq %r12 /* restrore R12 */
popq %r13 /* restrore R13 */
popq %r14 /* restrore R14 */
popq %r15 /* restrore R15 */
popq %rbx /* restrore RBX */
popq %rbp /* restrore RBP */
/* preserve ontop-function in R8 */
movq %rdx, %r8
/* return transfer_t from jump */
/* RAX == fctx, RDX == data */
movq %rsi, %rdx
/* pass transfer_t as first arg in context function */
/* RDI == fctx, RSI == data */
movq %rax, %rdi
/* keep return-address on stack */
/* indirect jump to context */
jmp *%r8
.size ontop_fcontext,.-ontop_fcontext
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits
/*
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 | 6 | 7 | *
* ---------------------------------------------------------------------------------- *
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
* ---------------------------------------------------------------------------------- *
* | R12 | R13 | R14 | R15 | *
* ---------------------------------------------------------------------------------- *
* ---------------------------------------------------------------------------------- *
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
* ---------------------------------------------------------------------------------- *
* | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
* ---------------------------------------------------------------------------------- *
* | RBX | RBP | RIP | EXIT | *
* ---------------------------------------------------------------------------------- *
* *
****************************************************************************************/
.text
.globl _ontop_fcontext
.align 8
_ontop_fcontext:
pushq %rbp /* save RBP */
pushq %rbx /* save RBX */
pushq %r15 /* save R15 */
pushq %r14 /* save R14 */
pushq %r13 /* save R13 */
pushq %r12 /* save R12 */
/* store RSP (pointing to context-data) in RAX */
movq %rsp, %rax
/* restore RSP (pointing to context-data) from RDI */
movq %rdi, %rsp
popq %r12 /* restrore R12 */
popq %r13 /* restrore R13 */
popq %r14 /* restrore R14 */
popq %r15 /* restrore R15 */
popq %rbx /* restrore RBX */
popq %rbp /* restrore RBP */
/* preserve ontop-function in R8 */
movq %rdx, %r8
/* return transfer_t from jump */
/* RAX == fctx, RDX == data */
movq %rsi, %rdx
/* pass transfer_t as first arg in context function */
/* RDI == fctx, RSI == data */
movq %rax, %rdi
/* keep return-address on stack */
/* indirect jump to context */
jmp *%r8
# This file is part of the ios-cmake project. It was retrieved from
# https://github.com/cristeab/ios-cmake.git, which is a fork of
# https://code.google.com/p/ios-cmake/. Which in turn is based off of
# the Platform/Darwin.cmake and Platform/UnixPaths.cmake files which
# are included with CMake 2.8.4
#
# The ios-cmake project is licensed under the new BSD license.
#
# Copyright (c) 2014, Bogdan Cristea and LTE Engineering Software,
# Kitware, Inc., Insight Software Consortium. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# This file is based off of the Platform/Darwin.cmake and
# Platform/UnixPaths.cmake files which are included with CMake 2.8.4
# It has been altered for iOS development.
#
# Updated by Alex Stewart (alexs.mac@gmail.com)
#
# *****************************************************************************
# Now maintained by Alexander Widerberg (widerbergaren [at] gmail.com)
# under the BSD-3-Clause license
# *****************************************************************************
#
# INFORMATION / HELP
#
# The following variables control the behaviour of this toolchain:
#
# IOS_PLATFORM: OS (default) or SIMULATOR or SIMULATOR64 or TVOS or SIMULATOR_TVOS
# OS = Build for iPhoneOS.
# SIMULATOR = Build for x86 i386 iPhone Simulator.
# SIMULATOR64 = Build for x86_64 iPhone Simulator.
# TVOS = Build for AppleTVOS.
# SIMULATOR_TVOS = Build for x86_64 AppleTV Simulator.
# CMAKE_OSX_SYSROOT: Path to the iOS SDK to use. By default this is
# automatically determined from IOS_PLATFORM and xcodebuild, but
# can also be manually specified (although this should not be required).
# CMAKE_IOS_DEVELOPER_ROOT: Path to the Developer directory for the iOS platform
# being compiled for. By default this is automatically determined from
# CMAKE_OSX_SYSROOT, but can also be manually specified (although this should
# not be required).
# ENABLE_BITCODE: (1|0) Enables or disables bitcode support. Default 1 (true)
# ENABLE_ARC: (1|0) Enables or disables ARC support. Default 1 (true, ARC enabled by default)
# ENABLE_VISIBILITY: (1|0) Enables or disables symbol visibility support. Default 0 (false, visibility hidden by default)
# IOS_ARCH: (armv7 armv7s arm64 i386 x86_64) If specified, will override the default architectures for the given IOS_PLATFORM
# OS = armv7 armv7s arm64
# SIMULATOR = i386
# SIMULATOR64 = x86_64
# TVOS = arm64
# SIMULATOR_TVOS = x86_64
#
# This toolchain defines the following variables for use externally:
#
# XCODE_VERSION: Version number (not including Build version) of Xcode detected.
# IOS_SDK_VERSION: Version of iOS SDK being used.
# CMAKE_OSX_ARCHITECTURES: Architectures being compiled for (generated from
# IOS_PLATFORM).
#
# This toolchain defines the following macros for use externally:
#
# set_xcode_property (TARGET XCODE_PROPERTY XCODE_VALUE XCODE_VARIANT)
# A convenience macro for setting xcode specific properties on targets.
# Available variants are: All, Release, RelWithDebInfo, Debug, MinSizeRel
# example: set_xcode_property (myioslib IPHONEOS_DEPLOYMENT_TARGET "3.1" "all").
#
# find_host_package (PROGRAM ARGS)
# A macro used to find executable programs on the host system, not within the
# iOS environment. Thanks to the android-cmake project for providing the
# command.
# Fix for PThread library not in path
set(CMAKE_THREAD_LIBS_INIT "-lpthread")
set(CMAKE_HAVE_THREADS_LIBRARY 1)
set(CMAKE_USE_WIN32_THREADS_INIT 0)
set(CMAKE_USE_PTHREADS_INIT 1)
# Get the Xcode version being used.
execute_process(COMMAND xcodebuild -version
OUTPUT_VARIABLE XCODE_VERSION
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REGEX MATCH "Xcode [0-9\\.]+" XCODE_VERSION "${XCODE_VERSION}")
string(REGEX REPLACE "Xcode ([0-9\\.]+)" "\\1" XCODE_VERSION "${XCODE_VERSION}")
message(STATUS "Building with Xcode version: ${XCODE_VERSION}")
# Default to building for iPhoneOS if not specified otherwise, and we cannot
# determine the platform from the CMAKE_OSX_ARCHITECTURES variable. The use
# of CMAKE_OSX_ARCHITECTURES is such that try_compile() projects can correctly
# determine the value of IOS_PLATFORM from the root project, as
# CMAKE_OSX_ARCHITECTURES is propagated to them by CMake.
if (NOT DEFINED IOS_PLATFORM)
if (CMAKE_OSX_ARCHITECTURES)
if (CMAKE_OSX_ARCHITECTURES MATCHES ".*arm.*")
set(IOS_PLATFORM "OS")
elseif (CMAKE_OSX_ARCHITECTURES MATCHES "i386")
set(IOS_PLATFORM "SIMULATOR")
elseif (CMAKE_OSX_ARCHITECTURES MATCHES "x86_64")
set(IOS_PLATFORM "SIMULATOR64")
endif()
endif()
if (NOT IOS_PLATFORM)
set(IOS_PLATFORM "OS")
endif()
endif()
set(IOS_PLATFORM ${IOS_PLATFORM} CACHE STRING
"Type of iOS platform for which to build.")
# Determine the platform name and architectures for use in xcodebuild commands
# from the specified IOS_PLATFORM name.
if (IOS_PLATFORM STREQUAL "OS")
set(XCODE_IOS_PLATFORM iphoneos)
if(NOT IOS_ARCH)
set(IOS_ARCH armv7 armv7s arm64)
endif()
elseif (IOS_PLATFORM STREQUAL "SIMULATOR")
set(XCODE_IOS_PLATFORM iphonesimulator)
if(NOT IOS_ARCH)
set(IOS_ARCH i386)
endif()
elseif(IOS_PLATFORM STREQUAL "SIMULATOR64")
set(XCODE_IOS_PLATFORM iphonesimulator)
if(NOT IOS_ARCH)
set(IOS_ARCH x86_64)
endif()
elseif (IOS_PLATFORM STREQUAL "TVOS")
set(XCODE_IOS_PLATFORM appletvos)
if(NOT IOS_ARCH)
set(IOS_ARCH arm64)
endif()
elseif (IOS_PLATFORM STREQUAL "SIMULATOR_TVOS")
set(XCODE_IOS_PLATFORM appletvsimulator)
if(NOT IOS_ARCH)
set(IOS_ARCH x86_64)
endif()
else()
message(FATAL_ERROR "Invalid IOS_PLATFORM: ${IOS_PLATFORM}")
endif()
message(STATUS "Configuring iOS build for platform: ${IOS_PLATFORM}, "
"architecture(s): ${IOS_ARCH}")
# If user did not specify the SDK root to use, then query xcodebuild for it.
if (NOT CMAKE_OSX_SYSROOT)
execute_process(COMMAND xcodebuild -version -sdk ${XCODE_IOS_PLATFORM} Path
OUTPUT_VARIABLE CMAKE_OSX_SYSROOT
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Using SDK: ${CMAKE_OSX_SYSROOT} for platform: ${IOS_PLATFORM}")
endif()
if (NOT EXISTS ${CMAKE_OSX_SYSROOT})
message(FATAL_ERROR "Invalid CMAKE_OSX_SYSROOT: ${CMAKE_OSX_SYSROOT} "
"does not exist.")
endif()
# Specify minimum version of deployment target.
if (NOT DEFINED IOS_DEPLOYMENT_TARGET)
# Unless specified, SDK version 8.0 is used by default as minimum target version.
set(IOS_DEPLOYMENT_TARGET "8.0"
CACHE STRING "Minimum iOS version to build for." )
message(STATUS "Using the default min-version since IOS_DEPLOYMENT_TARGET not provided!")
endif()
# Use bitcode or not
if (NOT DEFINED ENABLE_BITCODE AND NOT IOS_ARCH MATCHES "((^|, )(i386|x86_64))+")
# Unless specified, enable bitcode support by default
set(ENABLE_BITCODE TRUE CACHE BOOL "Whether or not to enable bitcode")
message(STATUS "Enabling bitcode support by default. ENABLE_BITCODE not provided!")
endif()
if (NOT DEFINED ENABLE_BITCODE)
message(STATUS "Disabling bitcode support by default on simulators. ENABLE_BITCODE not provided for override!")
endif()
# Use ARC or not
if (NOT DEFINED ENABLE_ARC)
# Unless specified, enable ARC support by default
set(ENABLE_ARC TRUE CACHE BOOL "Whether or not to enable ARC")
message(STATUS "Enabling ARC support by default. ENABLE_ARC not provided!")
endif()
# Use hidden visibility or not
if (NOT DEFINED ENABLE_VISIBILITY)
# Unless specified, disable symbols visibility by default
set(ENABLE_VISIBILITY FALSE CACHE BOOL "Whether or not to hide symbols (-fvisibility=hidden)")
message(STATUS "Hiding symbols visibility by default. ENABLE_VISIBILITY not provided!")
endif()
# Get the SDK version information.
execute_process(COMMAND xcodebuild -sdk ${CMAKE_OSX_SYSROOT} -version SDKVersion
OUTPUT_VARIABLE IOS_SDK_VERSION
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
# Find the Developer root for the specific iOS platform being compiled for
# from CMAKE_OSX_SYSROOT. Should be ../../ from SDK specified in
# CMAKE_OSX_SYSROOT. There does not appear to be a direct way to obtain
# this information from xcrun or xcodebuild.
if (NOT CMAKE_IOS_DEVELOPER_ROOT)
get_filename_component(IOS_PLATFORM_SDK_DIR ${CMAKE_OSX_SYSROOT} PATH)
get_filename_component(CMAKE_IOS_DEVELOPER_ROOT ${IOS_PLATFORM_SDK_DIR} PATH)
endif()
if (NOT EXISTS ${CMAKE_IOS_DEVELOPER_ROOT})
message(FATAL_ERROR "Invalid CMAKE_IOS_DEVELOPER_ROOT: "
"${CMAKE_IOS_DEVELOPER_ROOT} does not exist.")
endif()
# Find the C & C++ compilers for the specified SDK.
if (NOT CMAKE_C_COMPILER)
execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT} -find clang
OUTPUT_VARIABLE CMAKE_C_COMPILER
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Using C compiler: ${CMAKE_C_COMPILER}")
endif()
if (NOT CMAKE_CXX_COMPILER)
execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT} -find clang++
OUTPUT_VARIABLE CMAKE_CXX_COMPILER
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Using CXX compiler: ${CMAKE_CXX_COMPILER}")
endif()
# Find (Apple's) libtool.
execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT} -find libtool
OUTPUT_VARIABLE IOS_LIBTOOL
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Using libtool: ${IOS_LIBTOOL}")
# Configure libtool to be used instead of ar + ranlib to build static libraries.
# This is required on Xcode 7+, but should also work on previous versions of
# Xcode.
set(CMAKE_C_CREATE_STATIC_LIBRARY
"${IOS_LIBTOOL} -static -o <TARGET> <LINK_FLAGS> <OBJECTS> ")
set(CMAKE_CXX_CREATE_STATIC_LIBRARY
"${IOS_LIBTOOL} -static -o <TARGET> <LINK_FLAGS> <OBJECTS> ")
# Get the version of Darwin (OS X) of the host.
execute_process(COMMAND uname -r
OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
# Standard settings.
set(CMAKE_SYSTEM_NAME Darwin CACHE INTERNAL "")
set(CMAKE_SYSTEM_VERSION ${IOS_SDK_VERSION} CACHE INTERNAL "")
set(UNIX TRUE CACHE BOOL "")
set(APPLE TRUE CACHE BOOL "")
set(IOS TRUE CACHE BOOL "")
set(CMAKE_AR ar CACHE FILEPATH "" FORCE)
set(CMAKE_RANLIB ranlib CACHE FILEPATH "" FORCE)
# Force unset of OS X-specific deployment target (otherwise autopopulated),
# required as of cmake 2.8.10.
set(CMAKE_OSX_DEPLOYMENT_TARGET "" CACHE STRING
"Must be empty for iOS builds." FORCE)
# Set the architectures for which to build.
set(CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE STRING "Build architecture for iOS")
# Skip the platform compiler checks for cross compiling.
set(CMAKE_CXX_COMPILER_FORCED TRUE)
set(CMAKE_CXX_COMPILER_WORKS TRUE)
set(CMAKE_C_COMPILER_FORCED TRUE)
set(CMAKE_C_COMPILER_WORKS TRUE)
# All iOS/Darwin specific settings - some may be redundant.
set(CMAKE_SHARED_LIBRARY_PREFIX "lib")
set(CMAKE_SHARED_LIBRARY_SUFFIX ".dylib")
set(CMAKE_SHARED_MODULE_PREFIX "lib")
set(CMAKE_SHARED_MODULE_SUFFIX ".so")
set(CMAKE_C_COMPILER_ABI ELF)
set(CMAKE_CXX_COMPILER_ABI ELF)
set(CMAKE_C_HAS_ISYSROOT 1)
set(CMAKE_CXX_HAS_ISYSROOT 1)
set(CMAKE_MODULE_EXISTS 1)
set(CMAKE_DL_LIBS "")
set(CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ")
set(CMAKE_C_OSX_CURRENT_VERSION_FLAG "-current_version ")
set(CMAKE_CXX_OSX_COMPATIBILITY_VERSION_FLAG "${CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG}")
set(CMAKE_CXX_OSX_CURRENT_VERSION_FLAG "${CMAKE_C_OSX_CURRENT_VERSION_FLAG}")
if(IOS_ARCH MATCHES "((^|, )(arm64|x86_64))+")
set(CMAKE_C_SIZEOF_DATA_PTR 8)
set(CMAKE_CXX_SIZEOF_DATA_PTR 8)
message(STATUS "Using a data_ptr size of 8")
else()
set(CMAKE_C_SIZEOF_DATA_PTR 4)
set(CMAKE_CXX_SIZEOF_DATA_PTR 4)
message(STATUS "Using a data_ptr size of 4")
endif()
message(STATUS "Building for minimum iOS version: ${IOS_DEPLOYMENT_TARGET}"
" (SDK version: ${IOS_SDK_VERSION})")
# Note that only Xcode 7+ supports the newer more specific:
# -m${XCODE_IOS_PLATFORM}-version-min flags, older versions of Xcode use:
# -m(ios/ios-simulator)-version-min instead.
if (IOS_PLATFORM STREQUAL "OS")
if (XCODE_VERSION VERSION_LESS 7.0)
set(XCODE_IOS_PLATFORM_VERSION_FLAGS
"-mios-version-min=${IOS_DEPLOYMENT_TARGET}")
else()
# Xcode 7.0+ uses flags we can build directly from XCODE_IOS_PLATFORM.
set(XCODE_IOS_PLATFORM_VERSION_FLAGS
"-m${XCODE_IOS_PLATFORM}-version-min=${IOS_DEPLOYMENT_TARGET}")
endif()
elseif (IOS_PLATFORM STREQUAL "TVOS")
set(XCODE_IOS_PLATFORM_VERSION_FLAGS
"-mtvos-version-min=${IOS_DEPLOYMENT_TARGET}")
elseif (IOS_PLATFORM STREQUAL "SIMULATOR_TVOS")
set(XCODE_IOS_PLATFORM_VERSION_FLAGS
"-mtvos-simulator-version-min=${IOS_DEPLOYMENT_TARGET}")
else()
# SIMULATOR or SIMULATOR64 both use -mios-simulator-version-min.
set(XCODE_IOS_PLATFORM_VERSION_FLAGS
"-mios-simulator-version-min=${IOS_DEPLOYMENT_TARGET}")
endif()
message(STATUS "Version flags set to: ${XCODE_IOS_PLATFORM_VERSION_FLAGS}")
if (ENABLE_BITCODE)
set(BITCODE "-fembed-bitcode")
set(HEADER_PAD "")
message(STATUS "Enabling bitcode support.")
else()
set(BITCODE "")
set(HEADER_PAD "-headerpad_max_install_names")
message(STATUS "Disabling bitcode support.")
endif()
if (ENABLE_ARC)
set(FOBJC_ARC "-fobjc-arc")
message(STATUS "Enabling ARC support.")
else()
set(FOBJC_ARC "-fno-objc-arc")
message(STATUS "Disabling ARC support.")
endif()
if (NOT ENABLE_VISIBILITY)
set(VISIBILITY "-fvisibility=hidden")
message(STATUS "Hiding symbols (-fvisibility=hidden).")
else()
set(VISIBILITY "")
endif()
set(CMAKE_C_FLAGS
"${XCODE_IOS_PLATFORM_VERSION_FLAGS} ${BITCODE} -fobjc-abi-version=2 ${FOBJC_ARC} ${C_FLAGS}")
# Hidden visibilty is required for C++ on iOS.
set(CMAKE_CXX_FLAGS
"${XCODE_IOS_PLATFORM_VERSION_FLAGS} ${BITCODE} ${VISIBILITY} -fvisibility-inlines-hidden -fobjc-abi-version=2 ${FOBJC_ARC} ${CXX_FLAGS}")
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS} -DNDEBUG -Os -fomit-frame-pointer -ffast-math ${BITCODE} ${CXX_FLAGS_MINSIZEREL}")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS} -DNDEBUG -O2 -g -fomit-frame-pointer -ffast-math ${BITCODE} ${CXX_FLAGS_RELWITHDEBINFO}")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -DNDEBUG -O3 -fomit-frame-pointer -ffast-math ${BITCODE} ${CXX_FLAGS_RELEASE}")
set(CMAKE_C_LINK_FLAGS "${XCODE_IOS_PLATFORM_VERSION_FLAGS} -Wl,-search_paths_first ${C_LINK_FLAGS}")
set(CMAKE_CXX_LINK_FLAGS "${XCODE_IOS_PLATFORM_VERSION_FLAGS} -Wl,-search_paths_first ${CXX_LINK_FLAGS}")
# In order to ensure that the updated compiler flags are used in try_compile()
# tests, we have to forcibly set them in the CMake cache, not merely set them
# in the local scope.
list(APPEND VARS_TO_FORCE_IN_CACHE
CMAKE_C_FLAGS
CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS_RELEASE
CMAKE_C_LINK_FLAGS
CMAKE_CXX_LINK_FLAGS)
foreach(VAR_TO_FORCE ${VARS_TO_FORCE_IN_CACHE})
set(${VAR_TO_FORCE} "${${VAR_TO_FORCE}}" CACHE STRING "" FORCE)
endforeach()
set(CMAKE_PLATFORM_HAS_INSTALLNAME 1)
set (CMAKE_SHARED_LINKER_FLAGS "-rpath @executable_path/Frameworks -rpath @loader_path/Frameworks")
set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib ${HEADER_PAD}")
set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle ${HEADER_PAD}")
set(CMAKE_SHARED_MODULE_LOADER_C_FLAG "-Wl,-bundle_loader,")
set(CMAKE_SHARED_MODULE_LOADER_CXX_FLAG "-Wl,-bundle_loader,")
set(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib" ".so" ".a")
# Hack: if a new cmake (which uses CMAKE_INSTALL_NAME_TOOL) runs on an old
# build tree (where install_name_tool was hardcoded) and where
# CMAKE_INSTALL_NAME_TOOL isn't in the cache and still cmake didn't fail in
# CMakeFindBinUtils.cmake (because it isn't rerun) hardcode
# CMAKE_INSTALL_NAME_TOOL here to install_name_tool, so it behaves as it did
# before, Alex.
if (NOT DEFINED CMAKE_INSTALL_NAME_TOOL)
find_program(CMAKE_INSTALL_NAME_TOOL install_name_tool)
endif (NOT DEFINED CMAKE_INSTALL_NAME_TOOL)
# Set the find root to the iOS developer roots and to user defined paths.
set(CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT} ${CMAKE_OSX_SYSROOT}
${CMAKE_PREFIX_PATH} CACHE string "iOS find search path root" FORCE)
# Default to searching for frameworks first.
set(CMAKE_FIND_FRAMEWORK FIRST)
# Set up the default search directories for frameworks.
set(CMAKE_SYSTEM_FRAMEWORK_PATH
${CMAKE_OSX_SYSROOT}/System/Library/Frameworks
${CMAKE_OSX_SYSROOT}/System/Library/PrivateFrameworks
${CMAKE_OSX_SYSROOT}/Developer/Library/Frameworks)
# Only search the specified iOS SDK, not the remainder of the host filesystem.
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# This little macro lets you set any XCode specific property.
macro(set_xcode_property TARGET XCODE_PROPERTY XCODE_VALUE XCODE_RELVERSION)
set(XCODE_RELVERSION_I "${XCODE_RELVERSION}")
if (XCODE_RELVERSION_I STREQUAL "All")
set_property(TARGET ${TARGET} PROPERTY
XCODE_ATTRIBUTE_${XCODE_PROPERTY} "${XCODE_VALUE}")
else()
set_property(TARGET ${TARGET} PROPERTY
XCODE_ATTRIBUTE_${XCODE_PROPERTY}[variant=${XCODE_RELVERSION_I}] "${XCODE_VALUE}")
endif()
endmacro(set_xcode_property)
# This macro lets you find executable programs on the host system.
macro(find_host_package)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER)
set(IOS FALSE)
find_package(${ARGN})
set(IOS TRUE)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
endmacro(find_host_package)
#pragma once
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef void* fcontext_t;
typedef struct
{
fcontext_t ctx;
void* data;
} fcontext_transfer_t;
typedef struct
{
void* sptr;
size_t ssize;
} fcontext_stack_t;
/**
* Callback definition for context (coroutine)
*/
typedef void (*pfn_fcontext)(fcontext_transfer_t);
/**
* Switches to another context
* @param to Target context to switch to
* @param vp Custom user pointer to pass to new context
*/
fcontext_transfer_t jump_fcontext(fcontext_t const to, void * vp);
/**
* Make a new context
* @param sp Pointer to allocated stack memory
* @param size Stack memory size
* @param corofn Callback function for context (coroutine)
*/
fcontext_t make_fcontext(void * sp, size_t size, pfn_fcontext corofn);
fcontext_transfer_t ontop_fcontext(fcontext_t const to, void * vp, fcontext_transfer_t(*fn)(fcontext_transfer_t));
fcontext_stack_t create_fcontext_stack(size_t size);
void destroy_fcontext_stack(fcontext_stack_t* s);
#ifdef __cplusplus
}
#endif
\ No newline at end of file
#include <assert.h>
#include <math.h>
#include <string.h>
#include "fcontext.h"
// Detect posix
#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
/* UNIX-style OS. ------------------------------------------- */
# include <unistd.h>
# define _HAVE_POSIX 1
#endif
#ifdef _WIN32
# define WIN32_LEAN_AND_LEAN
# include <Windows.h>
/* 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)
/* Windows seams not to provide a constant or function
* telling the minimal stacksize */
# define MINSIGSTKSZ 8192
#else
# define MINSIGSTKSZ 4096
#endif
static size_t getPageSize()
{
SYSTEM_INFO si;
GetSystemInfo(&si);
return (size_t)si.dwPageSize;
}
static size_t getMinSize()
{
return MINSIGSTKSZ;
}
static size_t getMaxSize()
{
return 1 * 1024 * 1024 * 1024; /* 1GB */
}
static size_t getDefaultSize()
{
return 131072; // 128kb
}
#elif defined(_HAVE_POSIX)
#include <signal.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#if !defined (SIGSTKSZ)
# define SIGSTKSZ 131072 // 128kb recommended
# define UDEF_SIGSTKSZ
#endif
#if !defined (MINSIGSTKSZ)
# define MINSIGSTKSZ 32768 // 32kb minimum
# define UDEF_MINSIGSTKSZ
#endif
static size_t getPageSize()
{
/* conform to POSIX.1-2001 */
return (size_t)sysconf(_SC_PAGESIZE);
}
static size_t getMinSize()
{
return MINSIGSTKSZ;
}
static size_t getMaxSize()
{
struct rlimit limit;
getrlimit(RLIMIT_STACK, &limit);
return (size_t)limit.rlim_max;
}
static size_t getDefaultSize()
{
return SIGSTKSZ;
}
#endif
/* Stack allocation and protection*/
fcontext_stack_t create_fcontext_stack(size_t size)
{
size_t pages;
size_t size_;
void* vp;
fcontext_stack_t s;
s.sptr = NULL;
s.ssize = 0;
/* fix size */
if (size == 0)
size = getDefaultSize();
size_t minsz = getMinSize();
size_t maxsz = getMaxSize();
if (size < minsz)
size = minsz;
if (size > maxsz)
size = maxsz;
pages = (size_t)floorf((float)size/(float)getPageSize());
assert(pages >= 2); /* at least two pages must fit into stack (one page is guard-page) */
size_ = pages * getPageSize();
assert(size_ != 0 && size != 0);
assert(size_ <= size);
#ifdef _WIN32
vp = VirtualAlloc(0, size_, MEM_COMMIT, PAGE_READWRITE);
if (!vp)
return s;
DWORD old_options;
VirtualProtect(vp, getPageSize(), PAGE_READWRITE | PAGE_GUARD, &old_options);
#elif defined(_HAVE_POSIX)
# if defined(MAP_ANON)
vp = mmap(0, size_, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
# else
vp = mmap(0, size_, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
# endif
if (vp == MAP_FAILED)
return s;
mprotect(vp, getPageSize(), PROT_NONE);
#else
vp = malloc(size_);
if (!vp)
return s;
#endif
s.sptr = (char*)vp + size_;
s.ssize = size_;
return s;
}
void destroy_fcontext_stack(fcontext_stack_t* s)
{
void* vp;
assert(s->ssize >= getMinSize());
assert(s->ssize <= getMaxSize());
vp = (char*)s->sptr - s->ssize;
#ifdef _WIN32
VirtualFree(vp, 0, MEM_RELEASE);
#elif defined(_HAVE_POSIX)
munmap(vp, s->ssize);
#else
free(vp);
#endif
memset(s, 0x00, sizeof(fcontext_stack_t));
}
#ifdef UDEF_SIGSTKSZ
# undef SIGSTKSZ
#endif
#ifdef UDEF_MINSIGSTKSZ
# undef MINSIGSTKSZ
#endif
#ifdef _WIN32
# define WIN32_LEAN_AND_MEAN
# include <Windows.h>
#else
# include <time.h>
#endif
#include <stdio.h>
#include <fcontext/fcontext.h>
fcontext_t ctx;
fcontext_t ctx2;
static inline void fsleep(uint32_t _ms)
{
#ifdef _WIN32
Sleep(_ms);
#else
struct timespec req = { (time_t)_ms / 1000, (long)((_ms % 1000) * 1000000) };
struct timespec rem = { 0, 0 };
nanosleep(&req, &rem);
#endif
}
static void doo(fcontext_transfer_t t)
{
puts("DOO");
fsleep(1000);
jump_fcontext(t.ctx, NULL);
}
static void foo(fcontext_transfer_t t)
{
puts("FOO");
fsleep(1000);
jump_fcontext(ctx2, NULL);
puts("FOO 2");
fsleep(1000);
jump_fcontext(t.ctx, NULL);
}
int main()
{
fcontext_stack_t s = create_fcontext_stack(16 * 1024);
fcontext_stack_t s2 = create_fcontext_stack(0);
ctx = make_fcontext(s.sptr, s.ssize, foo);
ctx2 = make_fcontext(s2.sptr, s2.ssize, doo);
jump_fcontext(ctx, NULL);
puts("END");
destroy_fcontext_stack(&s);
destroy_fcontext_stack(&s2);
return 0;
}
\ No newline at end of file
#include "fiber_call.h"
namespace pls {
namespace internal {
namespace base {
}
}
}
#ifndef PREDICTABLE_PARALLEL_PATTERNS_APP_CONTEXT_SWITCH_FIBER_CALL_H_
#define PREDICTABLE_PARALLEL_PATTERNS_APP_CONTEXT_SWITCH_FIBER_CALL_H_
#include <utility>
#include <cstdio>
#include <cstdint>
#include <new>
namespace pls {
namespace internal {
namespace base {
using continuation_t = void *;
using stack_pointer_t = char *;
using callback_t = continuation_t (*)(continuation_t, void *);
template<typename F>
struct lambda_capture {
F lambda_;
explicit lambda_capture(F &&lambda) : lambda_{std::forward<F>(lambda)} {}
continuation_t operator()(continuation_t continuation) {
return lambda_(continuation);
}
};
template<typename T>
continuation_t execute_callable(continuation_t continuation, void *param) {
T *callable = reinterpret_cast<T *>(param);
continuation_t result = (*callable)(continuation);
callable->~T();
return result;
}
extern "C" {
continuation_t __fiber_call(stack_pointer_t stack_base,
void *callback_arg,
callback_t callback,
stack_pointer_t stack_limit);
continuation_t __fiber_continue(continuation_t continuation);
}
template<typename F>
static lambda_capture<F> *place_lambda_capture(F &&lambda, char *memory) {
return new(memory) lambda_capture<F>(std::forward<F>(lambda));
}
template<typename F>
continuation_t fiber_call(stack_pointer_t stack_memory, size_t stack_size, F &&lambda) {
stack_pointer_t lambda_memory = stack_memory + stack_size - sizeof(lambda_capture<F>);
auto *captured_lambda = place_lambda_capture(std::forward<F>(lambda), lambda_memory);
stack_pointer_t stack_base = lambda_memory;
stack_pointer_t stack_limit = stack_memory;
callback_t callback = execute_callable<lambda_capture<F>>;
return __fiber_call(stack_base, captured_lambda, callback, stack_limit);
}
}
}
}
#endif //PREDICTABLE_PARALLEL_PATTERNS_APP_CONTEXT_SWITCH_FIBER_CALL_H_
.file "fiber_call_x86_64.s" .file "fiber_call_x86_64.s"
.text .text
.global fiber_call .global __fiber_call
.type fiber_call, @function .type __fiber_call, @function
.align 16 .align 16
fiber_call: __fiber_call:
# rdi = address of new stack top and to store current stack top (parameter to function) # Parameter List (in order)
# r12 temporary for restoring old stack (callee saved, so we can take a 'fast' return path) # rdi = new stack pointer
# rsi = first parameter to callback
# rdx = callback function pointer
# rcx = new stack limit (not used on most platforms)
############### Register State Storage ################ # Return
# make space for all register state we will store # rax = continuation that returned control back to the caller (null if fallthrough)
# Variables
# r12 = temporary for the old stack pointer
############### Save State ###############
# Make space for all register state we will store.
leaq -0x38(%rsp), %rsp leaq -0x38(%rsp), %rsp
# store calee saved general registers # Store calee saved general registers.
movq %r12, 0x00(%rsp) movq %r12, 0x00(%rsp)
movq %r13, 0x08(%rsp) movq %r13, 0x08(%rsp)
movq %r14, 0x10(%rsp) movq %r14, 0x10(%rsp)
movq %r15, 0x18(%rsp) movq %r15, 0x18(%rsp)
movq %rbx, 0x20(%rsp) movq %rbx, 0x20(%rsp)
movq %rbp, 0x28(%rsp) movq %rbp, 0x28(%rsp)
# store MMX control- and status-word # Store MMX control- and status-word
stmxcsr 0x30(%rsp) stmxcsr 0x30(%rsp)
# store x87 control-word # Store x87 control-word
fnstcw 0x34(%rsp) fnstcw 0x34(%rsp)
############### Save State ###############
############### Stack Pointer Manipulation ############# # Perform change to new stack.
# keep the old stack pointer in a callee-saved register for 'fast' return path # Keep old stack as second parameter to our callback function.
movq %rsp, %r12 movq %rsp, %r12
# switch to new stack pointer # Make sure that stack start is properly aligned.
movq (%rdi), %rsp andq $-16, %rdi
# store old stack pointer # Switch to new stack pointer.
movq %r12, (%rdi) movq %rdi, %rsp
############# Function Call ############################ # Perform actual function call, this will now be on the new stack
# perform actual function call, this will now be on the new stack # rdi = first parametor to callback (continuation)
call callback # rsi = second parameter to callback (arbetary pointer)
# If someone else continued/jumped into this stored context we must not return here, movq %r12, %rdi
# thus we will never execute the rest of the function. call *%rdx
# Otherwise we can return out of the function as if it was a simple function call.
# Restore state of returned continuation.
############ Stack Pointer Manipulation ################ # To do so we first reset the stack pointer (which we get returned in rax).
# restore stack pointer that we had before # After that we execute our standard restore procedere to pop the state from the stack.
movq %r12, %rsp movq %rax, %rsp
############ Restore State Storage (as needed) ######### ############ Restore State ############
# ...we don't need to restore most registers (as they are calee saved). # restore calee saved general registers
# We only used %r12, so restore that and move back the stack pointer.
movq 0x00(%rsp), %r12 movq 0x00(%rsp), %r12
movq 0x08(%rsp), %r13
movq 0x10(%rsp), %r14
movq 0x18(%rsp), %r15
movq 0x20(%rsp), %rbx
movq 0x28(%rsp), %rbp
# restore MMX control- and status-word
ldmxcsr 0x30(%rsp)
# restore x87 control-word
fldcw 0x34(%rsp)
# release the space we used for storage # Free space for restored state
leaq 0x38(%rsp), %rsp leaq 0x38(%rsp), %rsp
############ Restore State ############
# TODO: Maybe look into a 'cleanup' hook for freeing the stack space here.
# just return back from the call # Just return back from the call.
# This is the end of a fiber, so we have no continuation.
xor %rax, %rax
ret ret
.file "fiber_continue_x86_64.s" .file "fiber_continue_x86_64.s"
.text .text
.global fiber_continue .global __fiber_continue
.type fiber_continue, @function .type __fiber_continue, @function
.align 16 .align 16
fiber_continue: __fiber_continue:
# rdi = address of new stack top and to store current stack top (parameter to function) # Parameter List (in order)
# rdi = pointer to continuation (should hold value of target stack will be filled with this continuation)
############### Register State Storage ################ # Return
# make space for all register state we will store # rax = continuation that returned control back to the caller (null if fallthrough)
# Variables
# r12 = temporary for the old stack pointer
############### Save State ###############
# Make space for all register state we will store.
leaq -0x38(%rsp), %rsp leaq -0x38(%rsp), %rsp
# store calee saved general registers # Store calee saved general registers.
movq %r12, 0x00(%rsp) movq %r12, 0x00(%rsp)
movq %r13, 0x08(%rsp) movq %r13, 0x08(%rsp)
movq %r14, 0x10(%rsp) movq %r14, 0x10(%rsp)
movq %r15, 0x18(%rsp) movq %r15, 0x18(%rsp)
movq %rbx, 0x20(%rsp) movq %rbx, 0x20(%rsp)
movq %rbp, 0x28(%rsp) movq %rbp, 0x28(%rsp)
# store MMX control- and status-word # Store MMX control- and status-word
stmxcsr 0x30(%rsp) stmxcsr 0x30(%rsp)
# store x87 control-word # Store x87 control-word
fnstcw 0x34(%rsp) fnstcw 0x34(%rsp)
############### Save State ###############
############### Stack Pointer Manipulation ############# # Perform change to new stack.
# keep the old stack # Keep old stack as second parameter to our callback function.
movq %rsp, %r12 movq %rsp, %r12
# switch to new stack pointer # switch to new stack pointer
movq (%rdi), %rsp movq %rdi, %rsp
# store old stack pointer
movq %r12, (%rdi)
# We stored our old execution context and are now on the target stack
# on which we would like to contiune our execution.
############ Restore State Storage (as needed) ######### ############ Restore State ############
# restore calee saved general registers # restore calee saved general registers
movq 0x00(%rsp), %r12 movq 0x00(%rsp), %r12
movq 0x08(%rsp), %r13 movq 0x08(%rsp), %r13
...@@ -49,6 +52,8 @@ fiber_continue: ...@@ -49,6 +52,8 @@ fiber_continue:
# Free space for restored state # Free space for restored state
leaq 0x38(%rsp), %rsp leaq 0x38(%rsp), %rsp
############ Restore State ############
# just return back from the call # Return the context we came from as a continuation.
movq %r12, %rax
ret ret
...@@ -3,31 +3,32 @@ ...@@ -3,31 +3,32 @@
#include <cstring> #include <cstring>
#include <chrono> #include <chrono>
#include "fcontext/fcontext.h"
#include "fiber_call.h"
using namespace std; using namespace std;
// Settings for stack and benchmark // Settings for stack and benchmark
const unsigned int NUM_RUNS = 100000; const size_t NUM_RUNS = 1000000;
const unsigned int STACK_SIZE = 512 * 8; const size_t STACK_SIZE = 512 * 1;
const unsigned char MAGIC_NUMBER = (unsigned char) 0xAB; const char MAGIC_NUMBER = (unsigned char) 0xAB;
// Memory for custom stack and continuation semantics // Memory for custom stack and continuation semantics
unsigned char custom_stack[STACK_SIZE] = {0}; char custom_stack[STACK_SIZE] = {0};
jmp_buf buffer; jmp_buf buffer;
// Example callback function and declaration of our assembly stack switching routine // Example callback function and declaration of our assembly stack switching routine
extern "C" { extern "C" {
void custom_stack_callback(void *); void custom_stack_callback(void *);
void fiber_call(void *);
void fiber_continue(void *);
void __attribute__ ((noinline)) callback() { void __attribute__ ((noinline)) callback() {
static volatile int tmp; static volatile int tmp;
tmp = 0; // Force at least a single memory write tmp = 0; // Force at least a single memory write
} }
} }
long __attribute__ ((noinline)) measure_function_call() { long measure_function_call() {
auto start_time = chrono::steady_clock::now(); auto start_time = chrono::steady_clock::now();
for (unsigned int i = 0; i < NUM_RUNS; i++) { for (unsigned int i = 0; i < NUM_RUNS; i++) {
callback(); callback();
...@@ -36,31 +37,31 @@ long __attribute__ ((noinline)) measure_function_call() { ...@@ -36,31 +37,31 @@ long __attribute__ ((noinline)) measure_function_call() {
return chrono::duration_cast<chrono::nanoseconds>(end_time - start_time).count(); return chrono::duration_cast<chrono::nanoseconds>(end_time - start_time).count();
} }
long __attribute__ ((noinline)) measure_stack_switch() { long measure_stack_switch() {
auto start_time = chrono::steady_clock::now(); auto start_time = chrono::steady_clock::now();
for (unsigned int i = 0; i < NUM_RUNS; i++) { for (unsigned int i = 0; i < NUM_RUNS; i++) {
custom_stack_callback(&custom_stack[STACK_SIZE - 16]); custom_stack_callback(&custom_stack[STACK_SIZE]);
} }
auto end_time = chrono::steady_clock::now(); auto end_time = chrono::steady_clock::now();
return chrono::duration_cast<chrono::nanoseconds>(end_time - start_time).count(); return chrono::duration_cast<chrono::nanoseconds>(end_time - start_time).count();
} }
long __attribute__ ((noinline)) measure_continuation() { long measure_continuation() {
auto start_time = chrono::steady_clock::now(); auto start_time = chrono::steady_clock::now();
for (unsigned int i = 0; i < NUM_RUNS; i++) { for (unsigned int i = 0; i < NUM_RUNS; i++) {
if (setjmp(buffer) == 0) { if (setjmp(buffer) == 0) {
custom_stack_callback(&custom_stack[STACK_SIZE - 16]); custom_stack_callback(&custom_stack[STACK_SIZE]);
} }
} }
auto end_time = chrono::steady_clock::now(); auto end_time = chrono::steady_clock::now();
return chrono::duration_cast<chrono::nanoseconds>(end_time - start_time).count(); return chrono::duration_cast<chrono::nanoseconds>(end_time - start_time).count();
} }
long __attribute__ ((noinline)) measure_continuation_and_jump() { long measure_continuation_and_jump() {
auto start_time = chrono::steady_clock::now(); auto start_time = chrono::steady_clock::now();
for (unsigned int i = 0; i < NUM_RUNS; i++) { for (unsigned int i = 0; i < NUM_RUNS; i++) {
if (setjmp(buffer) == 0) { if (setjmp(buffer) == 0) {
custom_stack_callback(&custom_stack[STACK_SIZE - 16]); custom_stack_callback(&custom_stack[STACK_SIZE]);
longjmp(buffer, 1); longjmp(buffer, 1);
} }
} }
...@@ -68,11 +69,63 @@ long __attribute__ ((noinline)) measure_continuation_and_jump() { ...@@ -68,11 +69,63 @@ long __attribute__ ((noinline)) measure_continuation_and_jump() {
return chrono::duration_cast<chrono::nanoseconds>(end_time - start_time).count(); return chrono::duration_cast<chrono::nanoseconds>(end_time - start_time).count();
} }
long __attribute__ ((noinline)) measure_fiber_call() { void fcontext_callback_fast(fcontext_transfer_t transfer) {
for (;;) {
callback();
jump_fcontext(transfer.ctx, nullptr);
}
}
long measure_fcontext_fast() {
fcontext_t context = make_fcontext(&custom_stack[STACK_SIZE], STACK_SIZE, &fcontext_callback_fast);
auto start_time = chrono::steady_clock::now();
for (unsigned int i = 0; i < NUM_RUNS; i++) {
context = jump_fcontext(context, nullptr).ctx;
}
auto end_time = chrono::steady_clock::now();
return chrono::duration_cast<chrono::nanoseconds>(end_time - start_time).count();
}
void fcontext_callback_clean(fcontext_transfer_t transfer) {
callback();
jump_fcontext(transfer.ctx, nullptr);
}
long measure_fcontext_clean() {
auto start_time = chrono::steady_clock::now(); auto start_time = chrono::steady_clock::now();
for (unsigned int i = 0; i < NUM_RUNS; i++) { for (unsigned int i = 0; i < NUM_RUNS; i++) {
void *stack_pointer = custom_stack; fcontext_t context = make_fcontext(&custom_stack[STACK_SIZE], STACK_SIZE, &fcontext_callback_clean);
fiber_call(&stack_pointer); jump_fcontext(context, nullptr);
}
auto end_time = chrono::steady_clock::now();
return chrono::duration_cast<chrono::nanoseconds>(end_time - start_time).count();
}
void fcontext_callcc(fcontext_transfer_t transfer) {
callback();
jump_fcontext(jump_fcontext(transfer.ctx, nullptr).ctx, nullptr);
}
long measure_fcontext_callcc() {
auto start_time = chrono::steady_clock::now();
for (unsigned int i = 0; i < NUM_RUNS; i++) {
fcontext_t context = make_fcontext(&custom_stack[STACK_SIZE], STACK_SIZE, &fcontext_callcc);
jump_fcontext(jump_fcontext(context, nullptr).ctx, nullptr);
}
auto end_time = chrono::steady_clock::now();
return chrono::duration_cast<chrono::nanoseconds>(end_time - start_time).count();
}
long measure_custom() {
using namespace pls::internal::base;
auto start_time = chrono::steady_clock::now();
for (unsigned int i = 0; i < NUM_RUNS; i++) {
fiber_call(custom_stack, STACK_SIZE, [](continuation_t continuation) {
callback();
return continuation;
});
} }
auto end_time = chrono::steady_clock::now(); auto end_time = chrono::steady_clock::now();
return chrono::duration_cast<chrono::nanoseconds>(end_time - start_time).count(); return chrono::duration_cast<chrono::nanoseconds>(end_time - start_time).count();
...@@ -85,20 +138,30 @@ int main() { ...@@ -85,20 +138,30 @@ int main() {
auto time_cont = measure_continuation(); auto time_cont = measure_continuation();
auto time_stack = measure_stack_switch(); auto time_stack = measure_stack_switch();
auto time_func = measure_function_call(); auto time_func = measure_function_call();
auto time_fiber = measure_fiber_call(); auto time_fcontext_fast = measure_fcontext_fast();
auto time_fcontext_clean = measure_fcontext_clean();
auto time_fcontext_calcc = measure_fcontext_callcc();
auto time_custom = measure_custom();
printf("Base\n");
printf("Function Call : %10ld, %5.5f\n", time_func, ((float) time_func / NUM_RUNS));
printf("Longjmp\n");
printf("Stack Switching : %10ld, %5.5f\n", time_stack, ((float) time_stack / NUM_RUNS));
printf("Full Continuation: %10ld, %5.5f\n", time_cont, ((float) time_cont / NUM_RUNS));
printf("Jump Continuation: %10ld, %5.5f\n", time_cont_jump, ((float) time_cont_jump / NUM_RUNS));
printf("Boost\n");
printf("FContext Fast : %10ld, %5.5f\n", time_fcontext_fast, ((float) time_fcontext_fast / NUM_RUNS));
printf("FContext Clean : %10ld, %5.5f\n", time_fcontext_clean, ((float) time_fcontext_clean / NUM_RUNS));
printf("FContext CallCC : %10ld, %5.5f\n", time_fcontext_calcc, ((float) time_fcontext_calcc / NUM_RUNS));
printf("Custom\n");
printf("Custom Fast Call : %10ld, %5.5f\n", time_custom, ((float) time_custom / NUM_RUNS));
for (unsigned int i = 0; i < STACK_SIZE; i++) { for (unsigned int i = 0; i < STACK_SIZE; i++) {
if (custom_stack[i] != MAGIC_NUMBER) { if (custom_stack[i] != MAGIC_NUMBER) {
printf("Used stack size about %u bytes.\n\n\n", (STACK_SIZE - i)); printf("\n\nUsed stack size about %u bytes.\n", (STACK_SIZE - i));
break; break;
} }
} }
printf("Function Call : %10ld, %5.5f\n", time_func, ((float) time_func / NUM_RUNS));
printf("Stack Switching : %10ld, %5.5f\n", time_stack, ((float) time_stack / NUM_RUNS));
printf("Full Continuation: %10ld, %5.5f\n", time_cont, ((float) time_cont / NUM_RUNS));
printf("Jump Continuation: %10ld, %5.5f\n", time_cont_jump, ((float) time_cont_jump / NUM_RUNS));
printf("Fiber Call : %10ld, %5.5f\n", time_fiber, ((float) time_fiber / NUM_RUNS));
return 0; return 0;
} }
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 sign in to comment