Mercurial > pub > dyncall > dyncall
annotate doc/manual/callconvs/callconv_x64.tex @ 340:6e33db95e724
- syscall infos in doc
author | Tassilo Philipp |
---|---|
date | Sat, 04 Jan 2020 22:48:51 +0100 |
parents | 74c056b597b7 |
children | c607d67cd6b8 |
rev | line source |
---|---|
0 | 1 %////////////////////////////////////////////////////////////////////////////// |
2 % | |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
3 % Copyright (c) 2007-2019 Daniel Adler <dadler@uni-goettingen.de>, |
0 | 4 % Tassilo Philipp <tphilipp@potion-studios.com> |
5 % | |
6 % Permission to use, copy, modify, and distribute this software for any | |
7 % purpose with or without fee is hereby granted, provided that the above | |
8 % copyright notice and this permission notice appear in all copies. | |
9 % | |
10 % THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
11 % WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
12 % MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
13 % ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
14 % WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
15 % ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
16 % OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
17 % | |
18 %////////////////////////////////////////////////////////////////////////////// | |
19 | |
20 % ================================================== | |
21 % x64 | |
22 % ================================================== | |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
23 \subsection{x64 Calling Conventions} |
0 | 24 |
25 | |
26 \paragraph{Overview} | |
27 | |
28 The x64 (64bit) architecture designed by AMD is based on Intel's x86 (32bit) | |
29 architecture, supporting it natively. It is sometimes referred to as x86-64, | |
30 AMD64, or, cloned by Intel, EM64T or Intel64.\\ | |
31 On this processor, a word is defined to be 16 bits in size, a dword 32 bits | |
32 and a qword 64 bits. Note that this is due to historical reasons (terminology | |
33 didn't change with the introduction of 32 and 64 bit processors).\\ | |
34 The x64 calling convention for MS Windows \cite{x64Win} differs from the | |
35 SystemV x64 calling convention \cite{x64SysV} used by Linux/*BSD/... | |
36 Note that this is not the only difference between these operating systems. The | |
37 64 bit programming model in use by 64 bit windows is LLP64, meaning that the C | |
38 types int and long remain 32 bits in size, whereas long long becomes 64 bits. | |
39 Under Linux/*BSD/... it's LP64.\\ | |
40 \\ | |
41 Compared to the x86 architecture, the 64 bit versions of the registers are | |
42 called rax, rbx, etc.. Furthermore, there are eight new general purpose | |
95 | 43 registers r8-r15.\\ |
0 | 44 |
45 | |
46 | |
47 \paragraph{\product{dyncall} support} | |
48 | |
340 | 49 Currently, the MS Windows and System V calling conventions are supported.\\ |
50 \product{Dyncall} can also be used to issue syscalls on System V platforms by | |
51 using the syscall number as target parameter and selecting the correct mode. | |
0 | 52 |
53 \subsubsection{MS Windows} | |
54 | |
55 \paragraph{Registers and register usage} | |
56 | |
57 \begin{table}[h] | |
77 | 58 \begin{tabular*}{0.95\textwidth}{3 B} |
0 | 59 Name & Brief description\\ |
60 \hline | |
61 {\bf rax} & scratch, return value\\ | |
62 {\bf rbx} & permanent\\ | |
63 {\bf rcx} & scratch, parameter 0 if integer or pointer\\ | |
64 {\bf rdx} & scratch, parameter 1 if integer or pointer\\ | |
65 {\bf rdi} & permanent\\ | |
66 {\bf rsi} & permanent\\ | |
276 | 67 {\bf rbp} & permanent, may be used as frame pointer\\ |
0 | 68 {\bf rsp} & stack pointer\\ |
69 {\bf r8-r9} & scratch, parameter 2 and 3 if integer or pointer\\ | |
70 {\bf r10-r11} & scratch, permanent if required by caller (used for syscall/sysret)\\ | |
71 {\bf r12-r15} & permanent\\ | |
72 {\bf xmm0} & scratch, floating point parameter 0, floating point return value\\ | |
73 {\bf xmm1-xmm3} & scratch, floating point parameters 1-3\\ | |
74 {\bf xmm4-xmm5} & scratch, permanent if required by caller\\ | |
75 {\bf xmm6-xmm15} & permanent\\ | |
76 | 76 \end{tabular*} |
0 | 77 \caption{Register usage on x64 MS Windows platform} |
78 \end{table} | |
79 | |
80 \paragraph{Parameter passing} | |
81 | |
82 \begin{itemize} | |
83 \item stack parameter order: right-to-left | |
84 \item caller cleans up the stack | |
85 \item first 4 integer/pointer parameters are passed via rcx, rdx, r8, r9 (from left to right), others are pushed on stack (there is a | |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
86 spill area for the first 4) |
0 | 87 \item float and double parameters are passed via xmm0l-xmm3l |
88 \item first 4 parameters are passed via the correct register depending on the parameter type - with mixed float and int parameters, | |
89 some registers are left out (e.g. first parameter ends up in rcx or xmm0, second in rdx or xmm1, etc.) | |
90 \item parameters in registers are right justified | |
91 \item parameters \textless\ 64bits are not zero extended - zero the upper bits contiaining garbage if needed (but they are always | |
92 passed as a qword) | |
93 \item parameters \textgreater\ 64 bit are passed by reference | |
94 \item if callee takes address of a parameter, first 4 parameters must be dumped (to the reserved space on the stack) - for | |
95 floating point parameters, value must be stored in integer AND floating point register | |
96 \item caller cleans up the stack, not the callee (like cdecl) | |
97 \item stack is always 16byte aligned - since return address is 64 bits in size, stacks with an odd number of parameters are | |
98 already aligned | |
331 | 99 \item ellipsis calls take floating point values in int and float registers (single precision floats are promoted to double precision as |
100 required by ellipsis calls) | |
0 | 101 \item if size of parameters \textgreater\ 1 page of memory (usually between 4k and 64k), chkstk must be called |
102 \end{itemize} | |
103 | |
104 | |
105 \paragraph{Return values} | |
106 | |
107 \begin{itemize} | |
108 \item return values of pointer or integral type (\textless=\ 64 bits) are returned via the rax register | |
109 \item floating point types are returned via the xmm0 register | |
110 \item for types \textgreater\ 64 bits, a secret first parameter with an address to the return value is passed | |
111 \end{itemize} | |
112 | |
113 | |
114 \paragraph{Stack layout} | |
115 | |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
116 Stack frame is always 16-byte aligned. |
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
117 % verified/amended: TP nov 2019 (@@@ no doc/disas_examples/x64.win.disas, yet...@@@) |
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
118 Stack directly after function prolog:\\ |
0 | 119 |
120 \begin{figure}[h] | |
121 \begin{tabular}{5|3|1 1} | |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
122 & \vdots & & \\ |
0 | 123 \hhline{~=~~} |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
124 register save area & \hspace{4cm} & & \mrrbrace{10}{caller's frame} \\ |
0 | 125 \hhline{~-~~} |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
126 local data & & & \\ |
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
127 \hhline{~-~~} |
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
128 \mrlbrace{7}{parameter area} & arg n-1 & \mrrbrace{3}{stack parameters} & \\ |
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
129 & \ldots & & \\ |
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
130 & arg 4 & & \\ |
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
131 & r9 or xmm3 & \mrrbrace{4}{spill area} & \\ |
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
132 & r8 or xmm2 & & \\ |
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
133 & rdx or xmm1 & & \\ |
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
134 & rcx or xmm0 & & \\ |
0 | 135 \hhline{~-~~} |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
136 & return address & & \\ |
0 | 137 \hhline{~=~~} |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
138 register save area & & & \mrrbrace{4}{current frame} \\ |
0 | 139 \hhline{~-~~} |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
140 local data & & & \\ |
0 | 141 \hhline{~-~~} |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
142 parameter area & & & \\ |
0 | 143 \hhline{~-~~} |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
144 & \vdots & & \\ |
0 | 145 \end{tabular} |
146 \caption{Stack layout on x64 Microsoft platform} | |
147 \end{figure} | |
148 | |
149 | |
150 | |
151 \newpage | |
152 | |
153 \subsubsection{System V (Linux / *BSD / MacOS X)} | |
154 | |
155 \paragraph{Registers and register usage} | |
156 | |
157 \begin{table}[h] | |
77 | 158 \begin{tabular*}{0.95\textwidth}{3 B} |
0 | 159 Name & Brief description\\ |
160 \hline | |
161 {\bf rax} & scratch, return value\\ | |
162 {\bf rbx} & permanent\\ | |
163 {\bf rcx} & scratch, parameter 3 if integer or pointer\\ | |
164 {\bf rdx} & scratch, parameter 2 if integer or pointer, return value\\ | |
165 {\bf rdi} & scratch, parameter 0 if integer or pointer\\ | |
166 {\bf rsi} & scratch, parameter 1 if integer or pointer\\ | |
276 | 167 {\bf rbp} & permanent, may be used as frame pointer\\ |
0 | 168 {\bf rsp} & stack pointer\\ |
169 {\bf r8-r9} & scratch, parameter 4 and 5 if integer or pointer\\ | |
170 {\bf r10-r11} & scratch\\ | |
171 {\bf r12-r15} & permanent\\ | |
172 {\bf xmm0} & scratch, floating point parameters 0, floating point return value\\ | |
173 {\bf xmm1-xmm7} & scratch, floating point parameters 1-7\\ | |
174 {\bf xmm8-xmm15} & scratch\\ | |
175 {\bf st0-st1} & scratch, 16 byte floating point return value\\ | |
176 {\bf st2-st7} & scratch\\ | |
76 | 177 \end{tabular*} |
0 | 178 \caption{Register usage on x64 System V (Linux/*BSD)} |
179 \end{table} | |
180 | |
181 \paragraph{Parameter passing} | |
182 | |
183 \begin{itemize} | |
184 \item stack parameter order: right-to-left | |
185 \item caller cleans up the stack | |
186 \item first 6 integer/pointer parameters are passed via rdi, rsi, rdx, rcx, r8, r9 | |
187 \item first 8 floating point parameters \textless=\ 64 bits are passed via xmm0l-xmm7l | |
188 \item parameters in registers are right justified | |
189 \item parameters that are not passed via registers are pushed onto the stack | |
190 \item parameters \textless\ 64bits are not zero extended - zero the upper bits contiaining garbage if needed (but they are always | |
191 passed as a qword) | |
192 \item integer/pointer parameters \textgreater\ 64 bit are passed via 2 registers | |
193 \item if callee takes address of a parameter, number of used xmm registers is passed silently in al (passed number mustn't be | |
194 exact but an upper bound on the number of used xmm registers) | |
195 \item stack is always 16byte aligned - since return address is 64 bits in size, stacks with an odd number of parameters are | |
196 already aligned | |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
197 \item no spill area is used on stack, iterating over varargs requires a specific va\_list implementation |
0 | 198 \end{itemize} |
199 | |
200 | |
201 \paragraph{Return values} | |
202 | |
203 \begin{itemize} | |
204 \item return values of pointer or integral type (\textless=\ 64 bits) are returned via the rax register | |
205 \item floating point types are returned via the xmm0 register | |
206 \item for types \textgreater\ 64 bits, a secret first parameter with an address to the return value is passed - the passed in address | |
207 will be returned in rax | |
208 \item floating point values \textgreater\ 64 bits are returned via st0 and st1 | |
209 \end{itemize} | |
210 | |
211 | |
212 \paragraph{Stack layout} | |
213 | |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
214 Stack frame is always 16-byte aligned. |
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
215 % verified/amended: TP nov 2019 (see also doc/disas_examples/x64.sysv.disas) |
0 | 216 Stack directly after function prolog:\\ |
217 | |
218 \begin{figure}[h] | |
219 \begin{tabular}{5|3|1 1} | |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
220 & \vdots & & \\ |
0 | 221 \hhline{~=~~} |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
222 register save area & \hspace{4cm} & & \mrrbrace{6}{caller's frame} \\ |
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
223 \hhline{~-~~} |
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
224 local data (with padding) & & & \\ |
0 | 225 \hhline{~-~~} |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
226 \mrlbrace{3}{parameter area} & arg n-1 & \mrrbrace{3}{stack parameters} & \\ |
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
227 & \ldots & & \\ |
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
228 & arg 6 & & \\ |
0 | 229 \hhline{~-~~} |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
230 & return address & & \\ |
0 | 231 \hhline{~=~~} |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
232 register save area & & & \mrrbrace{4}{current frame} \\ |
0 | 233 \hhline{~-~~} |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
234 local data & & & \\ |
0 | 235 \hhline{~-~~} |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
236 parameter area & & & \\ |
0 | 237 \hhline{~-~~} |
328
276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
Tassilo Philipp
parents:
276
diff
changeset
|
238 & \vdots & & \\ |
0 | 239 \end{tabular} |
240 \caption{Stack layout on x64 System V (Linux/*BSD)} | |
241 \end{figure} | |
242 | |
340 | 243 |
244 \newpage | |
245 | |
246 \subsubsection{System V syscalls} | |
247 | |
248 \paragraph{Parameter passing} | |
249 | |
250 \begin{itemize} | |
251 \item syscall is issued via the {\em syscall} instruction | |
252 \item kernel destroys registers rcx and r11 | |
253 \item syscall number is set in rax | |
254 \item up to 6 params are passed in the following registers in this order: rdi, rsi, rdx, rcx, r8, r9 | |
255 \item no stack in use, meaning syscalls are limited to six arguments | |
256 \item register rax holds the return value (values in between -4095 and -1 indicate errors) | |
257 \end{itemize} | |
258 |