• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! arm Linux system calls, using thumb-mode.
2 //!
3 //! In thumb-mode, r7 is the frame pointer and is not permitted to be used in
4 //! an inline asm operand, so we have to use a different register and copy it
5 //! into r7 inside the inline asm.
6 
7 use crate::backend::reg::{
8     ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0,
9 };
10 use core::arch::asm;
11 
12 #[inline]
syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg<R0>13 pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg<R0> {
14     let r0;
15     asm!(
16         "mov {tmp}, r7",
17         "mov r7, {nr}",
18         "svc 0",
19         "mov r7, {tmp}",
20         nr = in(reg) nr.to_asm(),
21         tmp = out(reg) _,
22         lateout("r0") r0,
23         options(nostack, preserves_flags, readonly)
24     );
25     FromAsm::from_asm(r0)
26 }
27 
28 #[inline]
syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0>29 pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> {
30     let r0;
31     asm!(
32         "mov {tmp}, r7",
33         "mov r7, {nr}",
34         "svc 0",
35         "mov r7, {tmp}",
36         nr = in(reg) nr.to_asm(),
37         tmp = out(reg) _,
38         inlateout("r0") a0.to_asm() => r0,
39         options(nostack, preserves_flags)
40     );
41     FromAsm::from_asm(r0)
42 }
43 
44 #[inline]
syscall1_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, ) -> RetReg<R0>45 pub(in crate::backend) unsafe fn syscall1_readonly(
46     nr: SyscallNumber<'_>,
47     a0: ArgReg<'_, A0>,
48 ) -> RetReg<R0> {
49     let r0;
50     asm!(
51         "mov {tmp}, r7",
52         "mov r7, {nr}",
53         "svc 0",
54         "mov r7, {tmp}",
55         nr = in(reg) nr.to_asm(),
56         tmp = out(reg) _,
57         inlateout("r0") a0.to_asm() => r0,
58         options(nostack, preserves_flags, readonly)
59     );
60     FromAsm::from_asm(r0)
61 }
62 
63 #[inline]
syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> !64 pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! {
65     asm!(
66         "mov r7, {nr}",
67         "svc 0",
68         nr = in(reg) nr.to_asm(),
69         in("r0") a0.to_asm(),
70         options(noreturn)
71     )
72 }
73 
74 #[inline]
syscall2( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, ) -> RetReg<R0>75 pub(in crate::backend) unsafe fn syscall2(
76     nr: SyscallNumber<'_>,
77     a0: ArgReg<'_, A0>,
78     a1: ArgReg<'_, A1>,
79 ) -> RetReg<R0> {
80     let r0;
81     asm!(
82         "mov {tmp}, r7",
83         "mov r7, {nr}",
84         "svc 0",
85         "mov r7, {tmp}",
86         nr = in(reg) nr.to_asm(),
87         tmp = out(reg) _,
88         inlateout("r0") a0.to_asm() => r0,
89         in("r1") a1.to_asm(),
90         options(nostack, preserves_flags)
91     );
92     FromAsm::from_asm(r0)
93 }
94 
95 #[inline]
syscall2_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, ) -> RetReg<R0>96 pub(in crate::backend) unsafe fn syscall2_readonly(
97     nr: SyscallNumber<'_>,
98     a0: ArgReg<'_, A0>,
99     a1: ArgReg<'_, A1>,
100 ) -> RetReg<R0> {
101     let r0;
102     asm!(
103         "mov {tmp}, r7",
104         "mov r7, {nr}",
105         "svc 0",
106         "mov r7, {tmp}",
107         nr = in(reg) nr.to_asm(),
108         tmp = out(reg) _,
109         inlateout("r0") a0.to_asm() => r0,
110         in("r1") a1.to_asm(),
111         options(nostack, preserves_flags, readonly)
112     );
113     FromAsm::from_asm(r0)
114 }
115 
116 #[inline]
syscall3( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, ) -> RetReg<R0>117 pub(in crate::backend) unsafe fn syscall3(
118     nr: SyscallNumber<'_>,
119     a0: ArgReg<'_, A0>,
120     a1: ArgReg<'_, A1>,
121     a2: ArgReg<'_, A2>,
122 ) -> RetReg<R0> {
123     let r0;
124     asm!(
125         "mov {tmp}, r7",
126         "mov r7, {nr}",
127         "svc 0",
128         "mov r7, {tmp}",
129         nr = in(reg) nr.to_asm(),
130         tmp = out(reg) _,
131         inlateout("r0") a0.to_asm() => r0,
132         in("r1") a1.to_asm(),
133         in("r2") a2.to_asm(),
134         options(nostack, preserves_flags)
135     );
136     FromAsm::from_asm(r0)
137 }
138 
139 #[inline]
syscall3_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, ) -> RetReg<R0>140 pub(in crate::backend) unsafe fn syscall3_readonly(
141     nr: SyscallNumber<'_>,
142     a0: ArgReg<'_, A0>,
143     a1: ArgReg<'_, A1>,
144     a2: ArgReg<'_, A2>,
145 ) -> RetReg<R0> {
146     let r0;
147     asm!(
148         "mov {tmp}, r7",
149         "mov r7, {nr}",
150         "svc 0",
151         "mov r7, {tmp}",
152         nr = in(reg) nr.to_asm(),
153         tmp = out(reg) _,
154         inlateout("r0") a0.to_asm() => r0,
155         in("r1") a1.to_asm(),
156         in("r2") a2.to_asm(),
157         options(nostack, preserves_flags, readonly)
158     );
159     FromAsm::from_asm(r0)
160 }
161 
162 #[inline]
syscall4( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, ) -> RetReg<R0>163 pub(in crate::backend) unsafe fn syscall4(
164     nr: SyscallNumber<'_>,
165     a0: ArgReg<'_, A0>,
166     a1: ArgReg<'_, A1>,
167     a2: ArgReg<'_, A2>,
168     a3: ArgReg<'_, A3>,
169 ) -> RetReg<R0> {
170     let r0;
171     asm!(
172         "mov {tmp}, r7",
173         "mov r7, {nr}",
174         "svc 0",
175         "mov r7, {tmp}",
176         nr = in(reg) nr.to_asm(),
177         tmp = out(reg) _,
178         inlateout("r0") a0.to_asm() => r0,
179         in("r1") a1.to_asm(),
180         in("r2") a2.to_asm(),
181         in("r3") a3.to_asm(),
182         options(nostack, preserves_flags)
183     );
184     FromAsm::from_asm(r0)
185 }
186 
187 #[inline]
syscall4_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, ) -> RetReg<R0>188 pub(in crate::backend) unsafe fn syscall4_readonly(
189     nr: SyscallNumber<'_>,
190     a0: ArgReg<'_, A0>,
191     a1: ArgReg<'_, A1>,
192     a2: ArgReg<'_, A2>,
193     a3: ArgReg<'_, A3>,
194 ) -> RetReg<R0> {
195     let r0;
196     asm!(
197         "mov {tmp}, r7",
198         "mov r7, {nr}",
199         "svc 0",
200         "mov r7, {tmp}",
201         nr = in(reg) nr.to_asm(),
202         tmp = out(reg) _,
203         inlateout("r0") a0.to_asm() => r0,
204         in("r1") a1.to_asm(),
205         in("r2") a2.to_asm(),
206         in("r3") a3.to_asm(),
207         options(nostack, preserves_flags, readonly)
208     );
209     FromAsm::from_asm(r0)
210 }
211 
212 #[inline]
syscall5( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, a4: ArgReg<'_, A4>, ) -> RetReg<R0>213 pub(in crate::backend) unsafe fn syscall5(
214     nr: SyscallNumber<'_>,
215     a0: ArgReg<'_, A0>,
216     a1: ArgReg<'_, A1>,
217     a2: ArgReg<'_, A2>,
218     a3: ArgReg<'_, A3>,
219     a4: ArgReg<'_, A4>,
220 ) -> RetReg<R0> {
221     let r0;
222     asm!(
223         "mov {tmp}, r7",
224         "mov r7, {nr}",
225         "svc 0",
226         "mov r7, {tmp}",
227         nr = in(reg) nr.to_asm(),
228         tmp = out(reg) _,
229         inlateout("r0") a0.to_asm() => r0,
230         in("r1") a1.to_asm(),
231         in("r2") a2.to_asm(),
232         in("r3") a3.to_asm(),
233         in("r4") a4.to_asm(),
234         options(nostack, preserves_flags)
235     );
236     FromAsm::from_asm(r0)
237 }
238 
239 #[inline]
syscall5_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, a4: ArgReg<'_, A4>, ) -> RetReg<R0>240 pub(in crate::backend) unsafe fn syscall5_readonly(
241     nr: SyscallNumber<'_>,
242     a0: ArgReg<'_, A0>,
243     a1: ArgReg<'_, A1>,
244     a2: ArgReg<'_, A2>,
245     a3: ArgReg<'_, A3>,
246     a4: ArgReg<'_, A4>,
247 ) -> RetReg<R0> {
248     let r0;
249     asm!(
250         "mov {tmp}, r7",
251         "mov r7, {nr}",
252         "svc 0",
253         "mov r7, {tmp}",
254         nr = in(reg) nr.to_asm(),
255         tmp = out(reg) _,
256         inlateout("r0") a0.to_asm() => r0,
257         in("r1") a1.to_asm(),
258         in("r2") a2.to_asm(),
259         in("r3") a3.to_asm(),
260         in("r4") a4.to_asm(),
261         options(nostack, preserves_flags, readonly)
262     );
263     FromAsm::from_asm(r0)
264 }
265 
266 #[inline]
syscall6( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, a4: ArgReg<'_, A4>, a5: ArgReg<'_, A5>, ) -> RetReg<R0>267 pub(in crate::backend) unsafe fn syscall6(
268     nr: SyscallNumber<'_>,
269     a0: ArgReg<'_, A0>,
270     a1: ArgReg<'_, A1>,
271     a2: ArgReg<'_, A2>,
272     a3: ArgReg<'_, A3>,
273     a4: ArgReg<'_, A4>,
274     a5: ArgReg<'_, A5>,
275 ) -> RetReg<R0> {
276     let r0;
277     asm!(
278         "mov {tmp}, r7",
279         "mov r7, {nr}",
280         "svc 0",
281         "mov r7, {tmp}",
282         nr = in(reg) nr.to_asm(),
283         tmp = out(reg) _,
284         inlateout("r0") a0.to_asm() => r0,
285         in("r1") a1.to_asm(),
286         in("r2") a2.to_asm(),
287         in("r3") a3.to_asm(),
288         in("r4") a4.to_asm(),
289         in("r5") a5.to_asm(),
290         options(nostack, preserves_flags)
291     );
292     FromAsm::from_asm(r0)
293 }
294 
295 #[inline]
syscall6_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, a4: ArgReg<'_, A4>, a5: ArgReg<'_, A5>, ) -> RetReg<R0>296 pub(in crate::backend) unsafe fn syscall6_readonly(
297     nr: SyscallNumber<'_>,
298     a0: ArgReg<'_, A0>,
299     a1: ArgReg<'_, A1>,
300     a2: ArgReg<'_, A2>,
301     a3: ArgReg<'_, A3>,
302     a4: ArgReg<'_, A4>,
303     a5: ArgReg<'_, A5>,
304 ) -> RetReg<R0> {
305     let r0;
306     asm!(
307         "mov {tmp}, r7",
308         "mov r7, {nr}",
309         "svc 0",
310         "mov r7, {tmp}",
311         nr = in(reg) nr.to_asm(),
312         tmp = out(reg) _,
313         inlateout("r0") a0.to_asm() => r0,
314         in("r1") a1.to_asm(),
315         in("r2") a2.to_asm(),
316         in("r3") a3.to_asm(),
317         in("r4") a4.to_asm(),
318         in("r5") a5.to_asm(),
319         options(nostack, preserves_flags, readonly)
320     );
321     FromAsm::from_asm(r0)
322 }
323