File: context.c

package info (click to toggle)
mongrel2 1.9.1-6
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 5,956 kB
  • sloc: ansic: 43,228; python: 2,827; sql: 1,555; makefile: 347; sh: 307; asm: 234; yacc: 145; php: 73; sed: 5
file content (121 lines) | stat: -rw-r--r-- 2,988 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/* Copyright (c) 2005-2006 Russ Cox, MIT; see COPYRIGHT */

#include "taskimpl.h"

#if defined(__APPLE__)
#if defined(__i386__)
#define NEEDX86MAKECONTEXT
#define NEEDSWAPCONTEXT
#elif defined(__x86_64__)
#define NEEDAMD64MAKECONTEXT
#define NEEDSWAPCONTEXT
#else
#define NEEDPOWERMAKECONTEXT
#define NEEDSWAPCONTEXT
#endif
#endif

#if defined(__FreeBSD__) && defined(__i386__) && __FreeBSD__ < 5
#define NEEDX86MAKECONTEXT
#define NEEDSWAPCONTEXT
#endif

#if defined(__OpenBSD__)
#if defined(__i386__)
#define NEEDX86MAKECONTEXT
#define NEEDSWAPCONTEXT
#elif defined(__x86_64__)
#define NEEDAMD64MAKECONTEXT
#define NEEDSWAPCONTEXT
#endif
#endif

#if 0 && defined(__linux__) && defined(__arm__)
#define NEEDSWAPCONTEXT
#define NEEDARMMAKECONTEXT
#endif

#ifdef NEEDPOWERMAKECONTEXT
void makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
{
    ulong *sp, *tos;
    va_list arg;

    tos = (ulong*)ucp->uc_stack.ss_sp+ucp->uc_stack.ss_size/sizeof(ulong);
    sp = tos - 16;    
    ucp->mc.pc = (long)func;
    ucp->mc.sp = (long)sp;
    va_start(arg, argc);
    ucp->mc.r3 = va_arg(arg, long);
    va_end(arg);
}
#endif

#ifdef NEEDX86MAKECONTEXT
void makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
{
    int *sp;

    sp = (int*)ucp->uc_stack.ss_sp+ucp->uc_stack.ss_size/4;
    sp -= argc;
    sp = (void*)((uintptr_t)sp - (uintptr_t)sp%16);    /* 16-align for OS X */
    memmove(sp, &argc+1, argc*sizeof(int));

    *--sp = 0;        /* return address */
    ucp->uc_mcontext.mc_eip = (long)func;
    ucp->uc_mcontext.mc_esp = (int)sp;
}
#endif

#ifdef NEEDAMD64MAKECONTEXT
void makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
{
    long *sp;
    va_list va;

    memset(&ucp->uc_mcontext, 0, sizeof ucp->uc_mcontext);
    if(argc != 2)
        *(int*)0 = 0;
    va_start(va, argc);
    ucp->uc_mcontext.mc_rdi = va_arg(va, int);
    ucp->uc_mcontext.mc_rsi = va_arg(va, int);
    va_end(va);
    sp = (long*)ucp->uc_stack.ss_sp+ucp->uc_stack.ss_size/sizeof(long);
    sp -= argc;
    sp = (void*)((uintptr_t)sp - (uintptr_t)sp%16);    /* 16-align for OS X */
    *--sp = 0;    /* return address */
    ucp->uc_mcontext.mc_rip = (long)func;
    ucp->uc_mcontext.mc_rsp = (long)sp;
}
#endif

#ifdef NEEDARMMAKECONTEXT
void makecontext(ucontext_t *uc, void (*fn)(void), int argc, ...)
{
    int i, *sp;
    va_list arg;
    
    sp = (int*)uc->uc_stack.ss_sp+uc->uc_stack.ss_size/4;
    va_start(arg, argc);
    
    if(argc-- > 0) uc->uc_mcontext.arm_r0 = va_arg(arg, uint);
    if(argc-- > 0) uc->uc_mcontext.arm_r1 = va_arg(arg, uint);
    if(argc-- > 0) uc->uc_mcontext.arm_r2 = va_arg(arg, uint);
    if(argc-- > 0) uc->uc_mcontext.arm_r3 = va_arg(arg, uint);

    va_end(arg);
    uc->uc_mcontext.arm_sp = (uint)sp;
    uc->uc_mcontext.arm_lr = (uint)fn;
}
#endif

#ifdef NEEDSWAPCONTEXT
int swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
{
    if(getcontext(oucp) == 0) {
        setcontext(ucp);
    }

    return 0;
}
#endif