1/*
2            Copyright Oliver Kowalke 2009.
3   Distributed under the Boost Software License, Version 1.0.
4      (See accompanying file LICENSE_1_0.txt or copy at
5          http://www.boost.org/LICENSE_1_0.txt)
6*/
7
8/*******************************************************
9 *                                                     *
10 *  -------------------------------------------------  *
11 *  |  0  |  4  |  8  |  12 |  16 |  20 |  24 |  28 |  *
12 *  -------------------------------------------------  *
13 *  |bchai|hiddn|   fpscr   |  PC |  CR | R14 | R15 |  *
14 *  -------------------------------------------------  *
15 *  -------------------------------------------------  *
16 *  |  32 |  36 |  40 |  44 |  48 |  52 |  56 |  60 |  *
17 *  -------------------------------------------------  *
18 *  | R16 | R17 | R18 | R19 | R20 | R21 | R22 | R23 |  *
19 *  -------------------------------------------------  *
20 *  -------------------------------------------------  *
21 *  |  64 |  68 |  72 |  76 |  80 |  84 |  88 |  92 |  *
22 *  -------------------------------------------------  *
23 *  | R24 | R25 | R26 | R27 | R28 | R29 | R30 | R31 |  *
24 *  -------------------------------------------------  *
25 *  -------------------------------------------------  *
26 *  |  96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 |  *
27 *  -------------------------------------------------  *
28 *  |    F14    |    F15    |    F16    |    F17    |  *
29 *  -------------------------------------------------  *
30 *  -------------------------------------------------  *
31 *  | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 |  *
32 *  -------------------------------------------------  *
33 *  |    F18    |    F19    |    F20    |    F21    |  *
34 *  -------------------------------------------------  *
35 *  -------------------------------------------------  *
36 *  | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 |  *
37 *  -------------------------------------------------  *
38 *  |    F22    |    F23    |    F24    |    F25    |  *
39 *  -------------------------------------------------  *
40 *  -------------------------------------------------  *
41 *  | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 |  *
42 *  -------------------------------------------------  *
43 *  |    F26    |    F27    |    F28    |    F29    |  *
44 *  -------------------------------------------------  *
45 *  ------------------------|------------              *
46 *  | 224 | 228 | 232 | 236 | 240 | 244 |              *
47 *  ------------------------|------------              *
48 *  |    F30    |    F31    |bchai|  LR |              *
49 *  ------------------------|------------              *
50 *                                                     *
51 *******************************************************/
52
53.file "make_ppc32_sysv_elf_gas.S"
54.text
55.globl make_fcontext
56.align 2
57.type make_fcontext,@function
58make_fcontext:
59    # save return address into R6
60    mflr  %r6
61
62    # first arg of make_fcontext() == top address of context-function
63    # shift address in R3 to lower 16 byte boundary
64    clrrwi  %r3, %r3, 4
65
66    # reserve space on context-stack, including 16 bytes of linkage
67    # and parameter area + 240 bytes of context-data (R1 % 16 == 0)
68    subi  %r3, %r3, 16 + 240
69
70    # third arg of make_fcontext() == address of context-function
71#ifdef __linux__
72    # save context-function as PC
73    stw  %r5, 16(%r3)
74#else
75    # save context-function for trampoline
76    stw  %r5, 248(%r3)
77#endif
78
79    # set back-chain to zero
80    li   %r0, 0
81    stw  %r0, 240(%r3)
82
83    # copy FPSCR to new context
84    mffs  %f0
85    stfd  %f0, 8(%r3)
86
87#ifdef __linux__
88    # set hidden pointer for returning transfer_t
89    la    %r0, 248(%r3)
90    stw   %r0, 4(%r3)
91#endif
92
93    # load address of label 1 into R4
94    bl  1f
951:  mflr  %r4
96#ifndef __linux__
97    # compute abs address of trampoline, use as PC
98    addi  %r7, %r4, trampoline - 1b
99    stw   %r7, 16(%r3)
100#endif
101    # compute abs address of label finish
102    addi  %r4, %r4, finish - 1b
103    # save address of finish as return-address for context-function
104    # will be entered after context-function returns
105    stw  %r4, 244(%r3)
106
107    # restore return address from R6
108    mtlr  %r6
109
110    blr  # return pointer to context-data
111
112#ifndef __linux__
113trampoline:
114    # On systems other than Linux, jump_fcontext is returning the
115    # transfer_t in R3:R4, but we need to pass transfer_t * R3 to
116    # our context-function.
117    lwz   %r0, 8(%r1)   # address of context-function
118    mtctr %r0
119    stw   %r3, 8(%r1)
120    stw   %r4, 12(%r1)
121    la    %r3, 8(%r1)   # address of transfer_t
122    bctr
123#endif
124
125finish:
126    # Use the secure PLT for _exit(0).  If we use the insecure BSS PLT
127    # here, then the linker may use the insecure BSS PLT even if the
128    # C++ compiler wanted the secure PLT.
129
130    # set R30 for secure PLT, large model
131    bl     2f
1322:  mflr   %r30
133    addis  %r30, %r30, .Ltoc - 2b@ha
134    addi   %r30, %r30, .Ltoc - 2b@l
135
136    # call _exit(0) with special addend 0x8000 for large model
137    li  %r3, 0
138    bl  _exit + 0x8000@plt
139.size make_fcontext, .-make_fcontext
140
141/* Provide the GOT pointer for secure PLT, large model. */
142.section .got2,"aw"
143.Ltoc = . + 0x8000
144
145/* Mark that we don't need executable stack.  */
146.section .note.GNU-stack,"",%progbits
147