asm unexecutable stack
[openafs.git] / src / lwp / process.amd64.s
1 /* $Id$ */
2
3 /*
4  * Copyright (c) 2003,2005 Kungliga Tekniska Högskolan
5  * (Royal Institute of Technology, Stockholm, Sweden).
6  * All rights reserved.
7  * 
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 
19  * 3. Neither the name of the Institute nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  * 
23  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35
36 /* x86_64 Assembly
37  *
38  * By Harald Barth <haba@stacken.kth.se> after looking
39  * at Derek Atkins' i386 routines and realizing that
40  * there were some differences and it was not enough
41  * just renaming the registers.
42  */
43         
44 #ifdef HAVE_MACHINE_ASM_H
45 #include <machine/asm.h>
46 #endif
47
48 #include <lwp_elf.h>
49         
50 #if defined(__linux__) && defined(__ELF__)
51         .section .note.GNU-stack,"",%progbits
52 #endif
53
54         .file "process.s"
55         .data
56         .text
57
58 /*
59  * struct savearea {
60  *    char    *topstack;
61  * }
62  */
63
64         .set    topstack,0
65
66 /*
67  * savecontext(int (*f)(), struct savearea *area1, char *newsp)
68  */
69
70 /* 
71  * In spite of passing arguments in registers, gcc first copies the content of the
72  * registers onto the stack. I do not know why gcc does this, but for now I mimic
73  * gcc's behaviour. Here are the offsets the arguments are copied to.
74  */
75         .set    f,-8
76         .set    area1,-16
77         .set    newsp,-24
78
79 .globl          _C_LABEL(PRE_Block)
80 .globl          _C_LABEL(savecontext)
81
82 ENTRY(savecontext)
83         pushq   %rbp                    /* The frame setup is just like gcc */
84         movq    %rsp,%rbp
85         subq    $32, %rsp               /* make room for args on the stack */
86         movq    %rdi, f(%rbp)           /* (3*8=24 but increments seem to */
87         movq    %rsi, area1(%rbp)       /* i multiples of 24, so 32 it is) */
88         movq    %rdx, newsp(%rbp)       /* and copy them there. */
89
90         movq    _C_LABEL(PRE_Block)@GOTPCREL(%rip), %rax
91         movl    $1,(%rax)               /* Do not allow any interrupts */
92
93         pushq   %rsp                    /* Push all registers onto the stack */
94         pushq   %rax                    /* Probably not _all_ are necessary */
95         pushq   %rcx                    /* but better one too much than one */
96         pushq   %rdx                    /* forgotten */
97         pushq   %rbx
98         pushq   %rbp
99         pushq   %rsi
100         pushq   %rdi
101         pushq   %r8
102         pushq   %r9
103         pushq   %r10
104         pushq   %r11
105         pushq   %r12
106         pushq   %r13
107         pushq   %r14
108         pushq   %r15                    /* Btw, the pusha instruction is no more */
109
110         movq    area1(%rbp),%rax        /* rax = base of savearea */
111         movq    %rsp,topstack(%rax)     /* area->topstack = rsp */
112         movq    newsp(%rbp),%rax        /* rax = new sp */
113         cmpq    $0,%rax
114         je      L1                      /* if new sp is 0 then dont change rsp */
115         movq    %rax,%rsp               /* Change rsp to the new sp */
116 L1:
117         jmp     *f(%rbp)                /* jump to function pointer passed in arg */
118
119 /* Shouldnt be here....*/
120         call    _C_LABEL(abort)
121
122 /*
123  * returnto(struct savearea *area2)
124  */
125
126 /* Offset where we put arg - se savecontext */
127         .set    area2,-8
128
129 .globl          _C_LABEL(returnto)
130
131 ENTRY(returnto)
132         pushq   %rbp                    /* New frame, gcc style */
133         movq    %rsp, %rbp              /* See savecontext above */
134         subq    $16, %rsp               /* Make room for 2 args */
135         movq    %rdi, area2(%rbp)       /* use room to copy 1 arg */
136         movq    area2(%rbp),%rax        /* rax = area2 */
137         movq    topstack(%rax),%rsp     /* restore rsp from place relative rbp*/
138
139         popq    %r15                    /* Restore regs */
140         popq    %r14
141         popq    %r13
142         popq    %r12
143         popq    %r11
144         popq    %r10
145         popq    %r9
146         popq    %r8
147         popq    %rdi
148         popq    %rsi
149         popq    %rbp
150         popq    %rbx
151         popq    %rdx
152         popq    %rcx
153         popq    %rax
154         popq    %rsp                    /* See savecontext */
155
156         movq    _C_LABEL(PRE_Block)@GOTPCREL(%rip), %rax
157         movl    $0,(%rax)       
158         addq    $32, %rsp               /* We did rsp-32 above, correct that */
159         popq    %rbp
160         ret
161         
162 /* We never should get here, put in emergency brake as in i386 code */
163         pushq   $1234
164         call    _C_LABEL(abort)
165