mirror of
				https://sourceware.org/git/glibc.git
				synced 2025-11-03 20:53:13 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			128 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			128 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
/* Assembly code template for system call stubs.
 | 
						|
   Copyright (C) 2009-2025 Free Software Foundation, Inc.
 | 
						|
   This file is part of the GNU C Library.
 | 
						|
 | 
						|
   The GNU C Library is free software; you can redistribute it and/or
 | 
						|
   modify it under the terms of the GNU Lesser General Public
 | 
						|
   License as published by the Free Software Foundation; either
 | 
						|
   version 2.1 of the License, or (at your option) any later version.
 | 
						|
 | 
						|
   The GNU C Library is distributed in the hope that it will be useful,
 | 
						|
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
   Lesser General Public License for more details.
 | 
						|
 | 
						|
   You should have received a copy of the GNU Lesser General Public
 | 
						|
   License along with the GNU C Library; if not, see
 | 
						|
   <https://www.gnu.org/licenses/>.  */
 | 
						|
 | 
						|
/* The real guts of this work are in the macros defined in the
 | 
						|
   machine- and kernel-specific sysdep.h header file.  Cancellable syscalls
 | 
						|
   should be implemented using C implementation with SYSCALL_CANCEL macro.
 | 
						|
 | 
						|
   Each system call's object is built by a rule in sysd-syscalls
 | 
						|
   generated by make-syscalls.sh that #include's this file after
 | 
						|
   defining a few macros:
 | 
						|
	SYSCALL_NAME		syscall name
 | 
						|
	SYSCALL_NARGS		number of arguments this call takes
 | 
						|
	SYSCALL_ULONG_ARG_1	the first unsigned long int argument this
 | 
						|
				call takes.  0 means that there are no
 | 
						|
				unsigned long int arguments.
 | 
						|
	SYSCALL_ULONG_ARG_2	the second unsigned long int argument this
 | 
						|
				call takes.  0 means that there is at most
 | 
						|
				one unsigned long int argument.
 | 
						|
	SYSCALL_SYMBOL		primary symbol name
 | 
						|
	SYSCALL_NOERRNO		1 to define a no-errno version (see below)
 | 
						|
	SYSCALL_ERRVAL		1 to define an error-value version (see below)
 | 
						|
 | 
						|
   We used to simply pipe the correct three lines below through cpp into
 | 
						|
   the assembler.  The main reason to have this file instead is so that
 | 
						|
   stub objects can be assembled with -g and get source line information
 | 
						|
   that leads a user back to a source file and these fine comments.  The
 | 
						|
   average user otherwise has a hard time knowing which "syscall-like"
 | 
						|
   functions in libc are plain stubs and which have nontrivial C wrappers.
 | 
						|
   Some versions of the "plain" stub generation macros are more than a few
 | 
						|
   instructions long and the untrained eye might not distinguish them from
 | 
						|
   some compiled code that inexplicably lacks source line information.  */
 | 
						|
 | 
						|
#include <sysdep.h>
 | 
						|
 | 
						|
/* This indirection is needed so that SYMBOL gets macro-expanded.  */
 | 
						|
#define syscall_hidden_def(SYMBOL)		hidden_def (SYMBOL)
 | 
						|
 | 
						|
/* If PSEUDOS_HAVE_ULONG_INDICES is defined, PSEUDO and T_PSEUDO macros
 | 
						|
   have 2 extra arguments for unsigned long int arguments:
 | 
						|
     Extra argument 1: Position of the first unsigned long int argument.
 | 
						|
     Extra argument 2: Position of the second unsigned long int argument.
 | 
						|
 */
 | 
						|
#ifndef PSEUDOS_HAVE_ULONG_INDICES
 | 
						|
# undef SYSCALL_ULONG_ARG_1
 | 
						|
# define SYSCALL_ULONG_ARG_1 0
 | 
						|
#endif
 | 
						|
 | 
						|
#if SYSCALL_ULONG_ARG_1
 | 
						|
# define T_PSEUDO(SYMBOL, NAME, N, U1, U2) \
 | 
						|
  PSEUDO (SYMBOL, NAME, N, U1, U2)
 | 
						|
# define T_PSEUDO_NOERRNO(SYMBOL, NAME, N, U1, U2) \
 | 
						|
  PSEUDO_NOERRNO (SYMBOL, NAME, N, U1, U2)
 | 
						|
# define T_PSEUDO_ERRVAL(SYMBOL, NAME, N, U1, U2) \
 | 
						|
  PSEUDO_ERRVAL (SYMBOL, NAME, N, U1, U2)
 | 
						|
#else
 | 
						|
# define T_PSEUDO(SYMBOL, NAME, N) \
 | 
						|
  PSEUDO (SYMBOL, NAME, N)
 | 
						|
# define T_PSEUDO_NOERRNO(SYMBOL, NAME, N) \
 | 
						|
  PSEUDO_NOERRNO (SYMBOL, NAME, N)
 | 
						|
# define T_PSEUDO_ERRVAL(SYMBOL, NAME, N) \
 | 
						|
  PSEUDO_ERRVAL (SYMBOL, NAME, N)
 | 
						|
#endif
 | 
						|
#define T_PSEUDO_END(SYMBOL)			PSEUDO_END (SYMBOL)
 | 
						|
#define T_PSEUDO_END_NOERRNO(SYMBOL)		PSEUDO_END_NOERRNO (SYMBOL)
 | 
						|
#define T_PSEUDO_END_ERRVAL(SYMBOL)		PSEUDO_END_ERRVAL (SYMBOL)
 | 
						|
 | 
						|
#if SYSCALL_NOERRNO
 | 
						|
 | 
						|
/* This kind of system call stub never returns an error.
 | 
						|
   We return the return value register to the caller unexamined.  */
 | 
						|
 | 
						|
# if SYSCALL_ULONG_ARG_1
 | 
						|
T_PSEUDO_NOERRNO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS,
 | 
						|
		  SYSCALL_ULONG_ARG_1, SYSCALL_ULONG_ARG_2)
 | 
						|
# else
 | 
						|
T_PSEUDO_NOERRNO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
 | 
						|
# endif
 | 
						|
	ret_NOERRNO
 | 
						|
T_PSEUDO_END_NOERRNO (SYSCALL_SYMBOL)
 | 
						|
 | 
						|
#elif SYSCALL_ERRVAL
 | 
						|
 | 
						|
/* This kind of system call stub returns the errno code as its return
 | 
						|
   value, or zero for success.  We may massage the kernel's return value
 | 
						|
   to meet that ABI, but we never set errno here.  */
 | 
						|
 | 
						|
# if SYSCALL_ULONG_ARG_1
 | 
						|
T_PSEUDO_ERRVAL (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS,
 | 
						|
		 SYSCALL_ULONG_ARG_1, SYSCALL_ULONG_ARG_2)
 | 
						|
# else
 | 
						|
T_PSEUDO_ERRVAL (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
 | 
						|
# endif
 | 
						|
	ret_ERRVAL
 | 
						|
T_PSEUDO_END_ERRVAL (SYSCALL_SYMBOL)
 | 
						|
 | 
						|
#else
 | 
						|
 | 
						|
/* This is a "normal" system call stub: if there is an error,
 | 
						|
   it returns -1 and sets errno.  */
 | 
						|
 | 
						|
# if SYSCALL_ULONG_ARG_1
 | 
						|
T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS,
 | 
						|
	  SYSCALL_ULONG_ARG_1, SYSCALL_ULONG_ARG_2)
 | 
						|
# else
 | 
						|
T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
 | 
						|
# endif
 | 
						|
	ret
 | 
						|
T_PSEUDO_END (SYSCALL_SYMBOL)
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
syscall_hidden_def (SYSCALL_SYMBOL)
 |