~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/include/nolibc/arch-arm.h

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
  2 /*
  3  * ARM specific definitions for NOLIBC
  4  * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
  5  */
  6 
  7 #ifndef _NOLIBC_ARCH_ARM_H
  8 #define _NOLIBC_ARCH_ARM_H
  9 
 10 #include "compiler.h"
 11 #include "crt.h"
 12 
 13 /* Syscalls for ARM in ARM or Thumb modes :
 14  *   - registers are 32-bit
 15  *   - stack is 8-byte aligned
 16  *     ( http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka4127.html)
 17  *   - syscall number is passed in r7
 18  *   - arguments are in r0, r1, r2, r3, r4, r5
 19  *   - the system call is performed by calling svc #0
 20  *   - syscall return comes in r0.
 21  *   - only lr is clobbered.
 22  *   - the arguments are cast to long and assigned into the target registers
 23  *     which are then simply passed as registers to the asm code, so that we
 24  *     don't have to experience issues with register constraints.
 25  *   - the syscall number is always specified last in order to allow to force
 26  *     some registers before (gcc refuses a %-register at the last position).
 27  *   - in thumb mode without -fomit-frame-pointer, r7 is also used to store the
 28  *     frame pointer, and we cannot directly assign it as a register variable,
 29  *     nor can we clobber it. Instead we assign the r6 register and swap it
 30  *     with r7 before calling svc, and r6 is marked as clobbered.
 31  *     We're just using any regular register which we assign to r7 after saving
 32  *     it.
 33  *
 34  * Also, ARM supports the old_select syscall if newselect is not available
 35  */
 36 #define __ARCH_WANT_SYS_OLD_SELECT
 37 
 38 #if (defined(__THUMBEB__) || defined(__THUMBEL__)) && \
 39     !defined(NOLIBC_OMIT_FRAME_POINTER)
 40 /* swap r6,r7 needed in Thumb mode since we can't use nor clobber r7 */
 41 #define _NOLIBC_SYSCALL_REG         "r6"
 42 #define _NOLIBC_THUMB_SET_R7        "eor r7, r6\neor r6, r7\neor r7, r6\n"
 43 #define _NOLIBC_THUMB_RESTORE_R7    "mov r7, r6\n"
 44 
 45 #else  /* we're in ARM mode */
 46 /* in Arm mode we can directly use r7 */
 47 #define _NOLIBC_SYSCALL_REG         "r7"
 48 #define _NOLIBC_THUMB_SET_R7        ""
 49 #define _NOLIBC_THUMB_RESTORE_R7    ""
 50 
 51 #endif /* end THUMB */
 52 
 53 #define my_syscall0(num)                                                      \
 54 ({                                                                            \
 55         register long _num  __asm__(_NOLIBC_SYSCALL_REG) = (num);             \
 56         register long _arg1 __asm__ ("r0");                                   \
 57                                                                               \
 58         __asm__ volatile (                                                    \
 59                 _NOLIBC_THUMB_SET_R7                                          \
 60                 "svc #0\n"                                                    \
 61                 _NOLIBC_THUMB_RESTORE_R7                                      \
 62                 : "=r"(_arg1), "=r"(_num)                                     \
 63                 : "r"(_arg1),                                                 \
 64                   "r"(_num)                                                   \
 65                 : "memory", "cc", "lr"                                        \
 66         );                                                                    \
 67         _arg1;                                                                \
 68 })
 69 
 70 #define my_syscall1(num, arg1)                                                \
 71 ({                                                                            \
 72         register long _num  __asm__(_NOLIBC_SYSCALL_REG) = (num);             \
 73         register long _arg1 __asm__ ("r0") = (long)(arg1);                    \
 74                                                                               \
 75         __asm__ volatile (                                                    \
 76                 _NOLIBC_THUMB_SET_R7                                          \
 77                 "svc #0\n"                                                    \
 78                 _NOLIBC_THUMB_RESTORE_R7                                      \
 79                 : "=r"(_arg1), "=r" (_num)                                    \
 80                 : "r"(_arg1),                                                 \
 81                   "r"(_num)                                                   \
 82                 : "memory", "cc", "lr"                                        \
 83         );                                                                    \
 84         _arg1;                                                                \
 85 })
 86 
 87 #define my_syscall2(num, arg1, arg2)                                          \
 88 ({                                                                            \
 89         register long _num  __asm__(_NOLIBC_SYSCALL_REG) = (num);             \
 90         register long _arg1 __asm__ ("r0") = (long)(arg1);                    \
 91         register long _arg2 __asm__ ("r1") = (long)(arg2);                    \
 92                                                                               \
 93         __asm__ volatile (                                                    \
 94                 _NOLIBC_THUMB_SET_R7                                          \
 95                 "svc #0\n"                                                    \
 96                 _NOLIBC_THUMB_RESTORE_R7                                      \
 97                 : "=r"(_arg1), "=r" (_num)                                    \
 98                 : "r"(_arg1), "r"(_arg2),                                     \
 99                   "r"(_num)                                                   \
100                 : "memory", "cc", "lr"                                        \
101         );                                                                    \
102         _arg1;                                                                \
103 })
104 
105 #define my_syscall3(num, arg1, arg2, arg3)                                    \
106 ({                                                                            \
107         register long _num  __asm__(_NOLIBC_SYSCALL_REG) = (num);             \
108         register long _arg1 __asm__ ("r0") = (long)(arg1);                    \
109         register long _arg2 __asm__ ("r1") = (long)(arg2);                    \
110         register long _arg3 __asm__ ("r2") = (long)(arg3);                    \
111                                                                               \
112         __asm__ volatile (                                                    \
113                 _NOLIBC_THUMB_SET_R7                                          \
114                 "svc #0\n"                                                    \
115                 _NOLIBC_THUMB_RESTORE_R7                                      \
116                 : "=r"(_arg1), "=r" (_num)                                    \
117                 : "r"(_arg1), "r"(_arg2), "r"(_arg3),                         \
118                   "r"(_num)                                                   \
119                 : "memory", "cc", "lr"                                        \
120         );                                                                    \
121         _arg1;                                                                \
122 })
123 
124 #define my_syscall4(num, arg1, arg2, arg3, arg4)                              \
125 ({                                                                            \
126         register long _num  __asm__(_NOLIBC_SYSCALL_REG) = (num);             \
127         register long _arg1 __asm__ ("r0") = (long)(arg1);                    \
128         register long _arg2 __asm__ ("r1") = (long)(arg2);                    \
129         register long _arg3 __asm__ ("r2") = (long)(arg3);                    \
130         register long _arg4 __asm__ ("r3") = (long)(arg4);                    \
131                                                                               \
132         __asm__ volatile (                                                    \
133                 _NOLIBC_THUMB_SET_R7                                          \
134                 "svc #0\n"                                                    \
135                 _NOLIBC_THUMB_RESTORE_R7                                      \
136                 : "=r"(_arg1), "=r" (_num)                                    \
137                 : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4),             \
138                   "r"(_num)                                                   \
139                 : "memory", "cc", "lr"                                        \
140         );                                                                    \
141         _arg1;                                                                \
142 })
143 
144 #define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)                        \
145 ({                                                                            \
146         register long _num  __asm__(_NOLIBC_SYSCALL_REG) = (num);             \
147         register long _arg1 __asm__ ("r0") = (long)(arg1);                    \
148         register long _arg2 __asm__ ("r1") = (long)(arg2);                    \
149         register long _arg3 __asm__ ("r2") = (long)(arg3);                    \
150         register long _arg4 __asm__ ("r3") = (long)(arg4);                    \
151         register long _arg5 __asm__ ("r4") = (long)(arg5);                    \
152                                                                               \
153         __asm__ volatile (                                                    \
154                 _NOLIBC_THUMB_SET_R7                                          \
155                 "svc #0\n"                                                    \
156                 _NOLIBC_THUMB_RESTORE_R7                                      \
157                 : "=r"(_arg1), "=r" (_num)                                    \
158                 : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
159                   "r"(_num)                                                   \
160                 : "memory", "cc", "lr"                                        \
161         );                                                                    \
162         _arg1;                                                                \
163 })
164 
165 #define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)                  \
166 ({                                                                            \
167         register long _num  __asm__(_NOLIBC_SYSCALL_REG) = (num);             \
168         register long _arg1 __asm__ ("r0") = (long)(arg1);                    \
169         register long _arg2 __asm__ ("r1") = (long)(arg2);                    \
170         register long _arg3 __asm__ ("r2") = (long)(arg3);                    \
171         register long _arg4 __asm__ ("r3") = (long)(arg4);                    \
172         register long _arg5 __asm__ ("r4") = (long)(arg5);                    \
173         register long _arg6 __asm__ ("r5") = (long)(arg6);                    \
174                                                                               \
175         __asm__ volatile (                                                    \
176                 _NOLIBC_THUMB_SET_R7                                          \
177                 "svc #0\n"                                                    \
178                 _NOLIBC_THUMB_RESTORE_R7                                      \
179                 : "=r"(_arg1), "=r" (_num)                                    \
180                 : "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
181                   "r"(_arg6), "r"(_num)                                       \
182                 : "memory", "cc", "lr"                                        \
183         );                                                                    \
184         _arg1;                                                                \
185 })
186 
187 /* startup code */
188 void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_stack_protector _start(void)
189 {
190         __asm__ volatile (
191                 "mov %r0, sp\n"         /* save stack pointer to %r0, as arg1 of _start_c */
192                 "and ip, %r0, #-8\n"    /* sp must be 8-byte aligned in the callee        */
193                 "mov sp, ip\n"
194                 "bl  _start_c\n"        /* transfer to c runtime                          */
195         );
196         __builtin_unreachable();
197 }
198 
199 #endif /* _NOLIBC_ARCH_ARM_H */
200 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php