blob: 81e5c066edfa0bac3bd00e7438fa4fddf5b15439 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#if defined MN_LINUX
#define sigsetjmp __sigsetjmp
#define CNAME(x) x
#elif defined MN_OSX
#define sigsetjmp sigsetjmp
#define CNAME(x) _ ## x
#elif defined MN_FreeBSD
#define sigsetjmp sigsetjmp
#define CNAME(x) x
#else
#error "unsupported platform"
#endif
.text
.code32
.p2align 4, 0x90 /* align on 16-byte boundary and fill with NOPs */
.globl CNAME(os_arch_frame_init)
.globl _os_arch_frame_init
/*
* void os_arch_frame_init(struct stack_frame *sf)
*/
CNAME(os_arch_frame_init):
push %ebp /* function prologue for backtrace */
mov %esp,%ebp
push %esi /* save %esi before using it as a tmpreg */
/*
* At this point we are executing on the main() stack:
* ----------------
* stack_frame ptr 0xc(%esp)
* ----------------
* return address 0x8(%esp)
* ----------------
* saved ebp 0x4(%esp)
* ----------------
* saved esi 0x0(%esp)
* ----------------
*/
movl 0xc(%esp),%esi /* %esi = 'sf' */
movl %esp,0x0(%esi) /* sf->mainsp = %esp */
/*
* Switch the stack so the stack pointer stored in 'sf->sf_jb' points
* to the task stack. This is slightly complicated because OS X wants
* the incoming stack pointer to be 16-byte aligned.
*
* ----------------
* sf (other fields)
* ----------------
* sf (sf_jb) 0x4(%esi)
* ----------------
* sf (sf_mainsp) 0x0(%esi)
* ----------------
* alignment padding variable (0 to 12 bytes)
* ----------------
* savemask (0) 0x4(%esp)
* ----------------
* pointer to sf_jb 0x0(%esp)
* ----------------
*/
movl %esi,%esp
subl $0x8,%esp /* make room for sigsetjmp() arguments */
andl $0xfffffff0,%esp /* align %esp on 16-byte boundary */
leal 0x4(%esi),%eax /* %eax = &sf->sf_jb */
movl %eax,0x0(%esp)
movl $0, 0x4(%esp)
call CNAME(sigsetjmp) /* sigsetjmp(sf->sf_jb, 0) */
test %eax,%eax
jne 1f
movl 0x0(%esi),%esp /* switch back to the main() stack */
pop %esi
pop %ebp
ret /* return to os_arch_task_stack_init() */
1:
lea 2f,%ecx
push %ecx /* retaddr */
push $0 /* frame pointer */
movl %esp,%ebp /* handcrafted prologue for backtrace */
push %eax /* rc */
push %esi /* sf */
call CNAME(os_arch_task_start) /* os_arch_task_start(sf, rc) */
/* never returns */
2:
nop