| author | |
| committer | |
| log | 5aeffab693a878679674f9a2f8bb2e6825da705d |
| tree | af0636f12bdd1e9064f14cedf3be76a1395bb797 |
| parent | 5b6d26e97bb97d79782f3c77b02a997e361a1497 |
it's needed for mipsel-linux-gnueabihf11 files changed, 1966 insertions(+), 0 deletions(-)
lib/libc/glibc/sysdeps/arc/sysdep.h created+53| ... | ... | @@ -0,0 +1,53 @@ |
| 1 | /* Assembler macros for ARC. | |
| 2 | Copyright (C) 2020-2021 Free Software Foundation, Inc. | |
| 3 | This file is part of the GNU C Library. | |
| 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | |
| 6 | modify it under the terms of the GNU Lesser General Public License as | |
| 7 | published by the Free Software Foundation; either version 2.1 of the | |
| 8 | License, or (at your option) any later version. | |
| 9 | ||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 13 | Lesser General Public License for more details. | |
| 14 | ||
| 15 | You should have received a copy of the GNU Lesser General Public | |
| 16 | License along with the GNU C Library; if not, see | |
| 17 | <https://www.gnu.org/licenses/>. */ | |
| 18 | ||
| 19 | #include <sysdeps/generic/sysdep.h> | |
| 20 | ||
| 21 | #ifdef	__ASSEMBLER__ | |
| 22 | ||
| 23 | /* Syntactic details of assembler. | |
| 24 | ; is not newline but comment, # is also for comment. */ | |
| 25 | # define ASM_SIZE_DIRECTIVE(name) .size name,.-name | |
| 26 | ||
| 27 | # define ENTRY(name)						\ | |
| 28 | 	.align 4				ASM_LINE_SEP	\ | |
| 29 | 	.globl C_SYMBOL_NAME(name)		ASM_LINE_SEP	\ | |
| 30 | 	.type C_SYMBOL_NAME(name),%function	ASM_LINE_SEP	\ | |
| 31 | 	C_LABEL(name)				ASM_LINE_SEP	\ | |
| 32 | 	cfi_startproc				ASM_LINE_SEP	\ | |
| 33 | 	CALL_MCOUNT | |
| 34 | ||
| 35 | # undef END | |
| 36 | # define END(name)						\ | |
| 37 | 	cfi_endproc				ASM_LINE_SEP	\ | |
| 38 | 	ASM_SIZE_DIRECTIVE(name) | |
| 39 | ||
| 40 | # ifdef SHARED | |
| 41 | # define PLTJMP(_x)	_x##@plt | |
| 42 | # else | |
| 43 | # define PLTJMP(_x)	_x | |
| 44 | # endif | |
| 45 | ||
| 46 | # define L(label) .L##label | |
| 47 | ||
| 48 | # define CALL_MCOUNT		/* Do nothing for now. */ | |
| 49 | ||
| 50 | # define STR(reg, rbase, off)	st reg, [rbase, off * 4] | |
| 51 | # define LDR(reg, rbase, off)	ld reg, [rbase, off * 4] | |
| 52 | ||
| 53 | #endif	/* __ASSEMBLER__ */ |
lib/libc/glibc/sysdeps/csky/sysdep.h created+84| ... | ... | @@ -0,0 +1,84 @@ |
| 1 | /* Assembler macros for C-SKY. | |
| 2 | Copyright (C) 2018-2021 Free Software Foundation, Inc. | |
| 3 | This file is part of the GNU C Library. | |
| 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | |
| 6 | modify it under the terms of the GNU Lesser General Public | |
| 7 | License as published by the Free Software Foundation; either | |
| 8 | version 2.1 of the License, or (at your option) any later version. | |
| 9 | ||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 13 | Lesser General Public License for more details. | |
| 14 | ||
| 15 | You should have received a copy of the GNU Lesser General Public | |
| 16 | License along with the GNU C Library. If not, see | |
| 17 | <https://www.gnu.org/licenses/>. */ | |
| 18 | ||
| 19 | #include <sysdeps/generic/sysdep.h> | |
| 20 | #include <features.h> | |
| 21 | ||
| 22 | #ifdef __ASSEMBLER__ | |
| 23 | ||
| 24 | # define ASM_SIZE_DIRECTIVE(name) .size name,.-name | |
| 25 | ||
| 26 | /* Define an entry point visible from C. */ | |
| 27 | # define ENTRY(name)		\ | |
| 28 | 	.globl name;		\ | |
| 29 | 	.type name,@function;	\ | |
| 30 | 	.align 4;		\ | |
| 31 | 	name##:;		\ | |
| 32 | 	cfi_startproc;		\ | |
| 33 | 	CALL_MCOUNT | |
| 34 | ||
| 35 | # undef END | |
| 36 | # define END(name)		\ | |
| 37 | 	cfi_endproc;		\ | |
| 38 | 	ASM_SIZE_DIRECTIVE(name) | |
| 39 | ||
| 40 | /* If compiled for profiling, call `mcount' at the start of each function. */ | |
| 41 | # ifdef PROF | |
| 42 | # ifdef __PIC__ | |
| 43 | # define CALL_MCOUNT				\ | |
| 44 | 	subi	sp, 4;				\ | |
| 45 | 	stw	lr, (sp, 0);			\ | |
| 46 | 	grs	t0, .Lgetpc;			\ | |
| 47 | .Lgetpc:					\ | |
| 48 | 	lrw	gb, .Lgetpc@GOTPC;		\ | |
| 49 | 	addu	gb, t0;				\ | |
| 50 | 	lrw	t1, _mcount@PLT;		\ | |
| 51 | 	ldr.w	t0, (gb, t1 << 0);		\ | |
| 52 | 	jmp	t0; | |
| 53 | # else | |
| 54 | # define CALL_MCOUNT				\ | |
| 55 | 	subi	sp, 4;				\ | |
| 56 | 	stw	lr, (sp, 0);			\ | |
| 57 | 	jbsr	_mcount; | |
| 58 | # endif | |
| 59 | # else | |
| 60 | # define CALL_MCOUNT	/* Do nothing. */ | |
| 61 | # endif | |
| 62 | ||
| 63 | # if defined (__CK860__) | |
| 64 | /* Instruction fetch will be faster when the label is 16 bytes aligned. | |
| 65 | Filling with nop instruction to avoid extra jump. */ | |
| 66 | # define LABLE_ALIGN	\ | |
| 67 | 	.balignw 16, 0x6c03 | |
| 68 | ||
| 69 | # define PRE_BNEZAD(R) | |
| 70 | ||
| 71 | # define BNEZAD(R, L)	\ | |
| 72 | 	bnezad	R, L | |
| 73 | # else | |
| 74 | # define LABLE_ALIGN	\ | |
| 75 | 	.balignw 8, 0x6c03 | |
| 76 | ||
| 77 | # define PRE_BNEZAD(R)	\ | |
| 78 | 	subi	R, 1 | |
| 79 | ||
| 80 | # define BNEZAD(R, L)	\ | |
| 81 | 	bnez	R, L | |
| 82 | # endif | |
| 83 | ||
| 84 | #endif |
lib/libc/glibc/sysdeps/nios2/sysdep.h created+65| ... | ... | @@ -0,0 +1,65 @@ |
| 1 | /* Assembler macros for Nios II. | |
| 2 | Copyright (C) 2015-2021 Free Software Foundation, Inc. | |
| 3 | This file is part of the GNU C Library. | |
| 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | |
| 6 | modify it under the terms of the GNU Lesser General Public License as | |
| 7 | published by the Free Software Foundation; either version 2.1 of the | |
| 8 | License, or (at your option) any later version. | |
| 9 | ||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 13 | Lesser General Public License for more details. | |
| 14 | ||
| 15 | You should have received a copy of the GNU Lesser General Public | |
| 16 | License along with the GNU C Library; if not, see | |
| 17 | <https://www.gnu.org/licenses/>. */ | |
| 18 | ||
| 19 | #include <sysdeps/generic/sysdep.h> | |
| 20 | ||
| 21 | #ifdef	__ASSEMBLER__ | |
| 22 | ||
| 23 | /* Syntactic details of assembler. */ | |
| 24 | ||
| 25 | #define ASM_SIZE_DIRECTIVE(name) .size name,.-name | |
| 26 | ||
| 27 | #define ENTRY(name)						 \ | |
| 28 | .globl C_SYMBOL_NAME(name);					 \ | |
| 29 | .type C_SYMBOL_NAME(name),%function;				 \ | |
| 30 | C_LABEL(name)							 \ | |
| 31 | cfi_startproc;						 \ | |
| 32 | CALL_MCOUNT; | |
| 33 | ||
| 34 | #undef END | |
| 35 | #define END(name)				\ | |
| 36 | cfi_endproc;					\ | |
| 37 | ASM_SIZE_DIRECTIVE(name) | |
| 38 | ||
| 39 | #ifdef PROF | |
| 40 | ||
| 41 | # ifdef __PIC__ | |
| 42 | # define CALL_MCOUNT				\ | |
| 43 | mov r8, ra;					\ | |
| 44 | nextpc r2;					\ | |
| 45 | 1:						\ | |
| 46 | movhi r3, %hiadj(_gp_got - 1b);		\ | |
| 47 | addi r3, r3, %lo(_gp_got - 1b);		\ | |
| 48 | add r2, r2, r3;				\ | |
| 49 | ldw r2, %call(_mcount)(r2);			\ | |
| 50 | callr r2;					\ | |
| 51 | mov ra, r8;					\ | |
| 52 | ret; | |
| 53 | # else | |
| 54 | # define CALL_MCOUNT				\ | |
| 55 | mov r8, ra;					\ | |
| 56 | call _mount;					\ | |
| 57 | mov ra, r8;					\ | |
| 58 | ret; | |
| 59 | # endif | |
| 60 | ||
| 61 | #else | |
| 62 | # define CALL_MCOUNT		/* Do nothing. */ | |
| 63 | #endif | |
| 64 | ||
| 65 | #endif	/* __ASSEMBLER__ */ |
lib/libc/glibc/sysdeps/unix/mips/mips64/sysdep.h created+65| ... | ... | @@ -0,0 +1,65 @@ |
| 1 | /* Copyright (C) 1992-2021 Free Software Foundation, Inc. | |
| 2 | This file is part of the GNU C Library. | |
| 3 | Contributed by Alexandre Oliva <aoliva@redhat.com>. | |
| 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | |
| 6 | modify it under the terms of the GNU Lesser General Public | |
| 7 | License as published by the Free Software Foundation; either | |
| 8 | version 2.1 of the License, or (at your option) any later version. | |
| 9 | ||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 13 | Lesser General Public License for more details. | |
| 14 | ||
| 15 | You should have received a copy of the GNU Lesser General Public | |
| 16 | License along with the GNU C Library. If not, see | |
| 17 | <https://www.gnu.org/licenses/>. */ | |
| 18 | ||
| 19 | #include <sysdeps/unix/mips/sysdep.h> | |
| 20 | ||
| 21 | #ifdef __ASSEMBLER__ | |
| 22 | #include <sys/asm.h> | |
| 23 | ||
| 24 | /* Note that while it's better structurally, going back to call __syscall_error | |
| 25 | can make things confusing if you're debugging---it looks like it's jumping | |
| 26 | backwards into the previous fn. */ | |
| 27 | #ifdef __PIC__ | |
| 28 | #define PSEUDO(name, syscall_name, args) \ | |
| 29 | .align 2;								 \ | |
| 30 | .set nomips16;							 \ | |
| 31 | cfi_startproc;							 \ | |
| 32 | 99:;									 \ | |
| 33 | .set noat;								 \ | |
| 34 | .cpsetup t9, $1, name;						 \ | |
| 35 | cfi_register (gp, $1);						 \ | |
| 36 | .set at;								 \ | |
| 37 | PTR_LA t9,__syscall_error;						 \ | |
| 38 | .cpreturn;								 \ | |
| 39 | cfi_restore (gp);							 \ | |
| 40 | jr t9;								 \ | |
| 41 | cfi_endproc;								 \ | |
| 42 | ENTRY(name)								 \ | |
| 43 | li v0, SYS_ify(syscall_name);						 \ | |
| 44 | syscall;								 \ | |
| 45 | bne a3, zero, 99b;							 \ | |
| 46 | L(syse1): | |
| 47 | #else | |
| 48 | #define PSEUDO(name, syscall_name, args) \ | |
| 49 | .set noreorder;							 \ | |
| 50 | .align 2;								 \ | |
| 51 | .set nomips16;							 \ | |
| 52 | cfi_startproc;							 \ | |
| 53 | 99: j __syscall_error;						 \ | |
| 54 | nop; \ | |
| 55 | cfi_endproc;								 \ | |
| 56 | ENTRY(name)								 \ | |
| 57 | .set noreorder;							 \ | |
| 58 | li v0, SYS_ify(syscall_name);						 \ | |
| 59 | syscall;								 \ | |
| 60 | .set reorder;								 \ | |
| 61 | bne a3, zero, 99b;							 \ | |
| 62 | L(syse1): | |
| 63 | #endif | |
| 64 | ||
| 65 | #endif |
lib/libc/glibc/sysdeps/unix/sysv/linux/arc/sysdep.h created+229| ... | ... | @@ -0,0 +1,229 @@ |
| 1 | /* Assembler macros for ARC. | |
| 2 | Copyright (C) 2020-2021 Free Software Foundation, Inc. | |
| 3 | This file is part of the GNU C Library. | |
| 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | |
| 6 | modify it under the terms of the GNU Lesser General Public | |
| 7 | License as published by the Free Software Foundation; either | |
| 8 | version 2.1 of the License, or (at your option) any later version. | |
| 9 | ||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 13 | Lesser General Public License for more details. | |
| 14 | ||
| 15 | You should have received a copy of the GNU Lesser General Public | |
| 16 | License along with the GNU C Library; if not, see | |
| 17 | <https://www.gnu.org/licenses/>. */ | |
| 18 | ||
| 19 | #ifndef _LINUX_ARC_SYSDEP_H | |
| 20 | #define _LINUX_ARC_SYSDEP_H 1 | |
| 21 | ||
| 22 | #include <sysdeps/arc/sysdep.h> | |
| 23 | #include <sysdeps/unix/sysv/linux/generic/sysdep.h> | |
| 24 | ||
| 25 | /* "workarounds" for generic code needing to handle 64-bit time_t. */ | |
| 26 | ||
| 27 | /* Fix sysdeps/unix/sysv/linux/clock_getcpuclockid.c. */ | |
| 28 | #define __NR_clock_getres	__NR_clock_getres_time64 | |
| 29 | /* Fix sysdeps/nptl/lowlevellock-futex.h. */ | |
| 30 | #define __NR_futex		__NR_futex_time64 | |
| 31 | /* Fix sysdeps/unix/sysv/linux/pause.c. */ | |
| 32 | #define __NR_ppoll		__NR_ppoll_time64 | |
| 33 | /* Fix sysdeps/unix/sysv/linux/select.c. */ | |
| 34 | #define __NR_pselect6		__NR_pselect6_time64 | |
| 35 | /* Fix sysdeps/unix/sysv/linux/recvmmsg.c. */ | |
| 36 | #define __NR_recvmmsg		__NR_recvmmsg_time64 | |
| 37 | /* Fix sysdeps/unix/sysv/linux/sigtimedwait.c. */ | |
| 38 | #define __NR_rt_sigtimedwait	__NR_rt_sigtimedwait_time64 | |
| 39 | /* Fix sysdeps/unix/sysv/linux/semtimedop.c. */ | |
| 40 | #define __NR_semtimedop		__NR_semtimedop_time64 | |
| 41 | /* Hack sysdeps/unix/sysv/linux/generic/utimes.c. */ | |
| 42 | #define __NR_utimensat		__NR_utimensat_time64 | |
| 43 | ||
| 44 | /* For RTLD_PRIVATE_ERRNO. */ | |
| 45 | #include <dl-sysdep.h> | |
| 46 | ||
| 47 | #include <tls.h> | |
| 48 | ||
| 49 | #undef SYS_ify | |
| 50 | #define SYS_ify(syscall_name) __NR_##syscall_name | |
| 51 | ||
| 52 | #ifdef __ASSEMBLER__ | |
| 53 | ||
| 54 | /* This is a "normal" system call stub: if there is an error, | |
| 55 | it returns -1 and sets errno. */ | |
| 56 | ||
| 57 | # undef PSEUDO | |
| 58 | # define PSEUDO(name, syscall_name, args)			\ | |
| 59 | PSEUDO_NOERRNO(name, syscall_name, args)	ASM_LINE_SEP	\ | |
| 60 | brhi r0, -4096, L (call_syscall_err)	ASM_LINE_SEP | |
| 61 | ||
| 62 | # define ret	j_s [blink] | |
| 63 | ||
| 64 | # undef PSEUDO_END | |
| 65 | # define PSEUDO_END(name)					\ | |
| 66 | SYSCALL_ERROR_HANDLER				ASM_LINE_SEP	\ | |
| 67 | END (name) | |
| 68 | ||
| 69 | /* --------- Helper for SYSCALL_NOERRNO ----------- | |
| 70 | This kind of system call stub never returns an error. | |
| 71 | We return the return value register to the caller unexamined. */ | |
| 72 | ||
| 73 | # undef PSEUDO_NOERRNO | |
| 74 | # define PSEUDO_NOERRNO(name, syscall_name, args)		\ | |
| 75 | .text						ASM_LINE_SEP	\ | |
| 76 | ENTRY (name)					ASM_LINE_SEP	\ | |
| 77 | DO_CALL (syscall_name, args)		ASM_LINE_SEP	\ | |
| 78 | ||
| 79 | /* Return the return value register unexamined. Since r0 is both | |
| 80 | syscall return reg and function return reg, no work needed. */ | |
| 81 | # define ret_NOERRNO						\ | |
| 82 | j_s [blink]		ASM_LINE_SEP | |
| 83 | ||
| 84 | # undef PSEUDO_END_NOERRNO | |
| 85 | # define PSEUDO_END_NOERRNO(name)				\ | |
| 86 | END (name) | |
| 87 | ||
| 88 | /* --------- Helper for SYSCALL_ERRVAL ----------- | |
| 89 | This kind of system call stub returns the errno code as its return | |
| 90 | value, or zero for success. We may massage the kernel's return value | |
| 91 | to meet that ABI, but we never set errno here. */ | |
| 92 | ||
| 93 | # undef PSEUDO_ERRVAL | |
| 94 | # define PSEUDO_ERRVAL(name, syscall_name, args)		\ | |
| 95 | PSEUDO_NOERRNO(name, syscall_name, args)	ASM_LINE_SEP | |
| 96 | ||
| 97 | /* Don't set errno, return kernel error (in errno form) or zero. */ | |
| 98 | # define ret_ERRVAL						\ | |
| 99 | rsub r0, r0, 0				ASM_LINE_SEP	\ | |
| 100 | ret_NOERRNO | |
| 101 | ||
| 102 | # undef PSEUDO_END_ERRVAL | |
| 103 | # define PSEUDO_END_ERRVAL(name)				\ | |
| 104 | END (name) | |
| 105 | ||
| 106 | ||
| 107 | /* To reduce the code footprint, we confine the actual errno access | |
| 108 | to single place in __syscall_error(). | |
| 109 | This takes raw kernel error value, sets errno and returns -1. */ | |
| 110 | # if IS_IN (libc) | |
| 111 | # define CALL_ERRNO_SETTER_C	bl PLTJMP(HIDDEN_JUMPTARGET(__syscall_error)) | |
| 112 | # else | |
| 113 | # define CALL_ERRNO_SETTER_C	bl PLTJMP(__syscall_error) | |
| 114 | # endif | |
| 115 | ||
| 116 | # define SYSCALL_ERROR_HANDLER				\ | |
| 117 | L (call_syscall_err):			ASM_LINE_SEP	\ | |
| 118 | push_s blink			ASM_LINE_SEP	\ | |
| 119 | cfi_adjust_cfa_offset (4)		ASM_LINE_SEP	\ | |
| 120 | cfi_rel_offset (blink, 0)		ASM_LINE_SEP	\ | |
| 121 | CALL_ERRNO_SETTER_C			ASM_LINE_SEP	\ | |
| 122 | pop_s blink			ASM_LINE_SEP	\ | |
| 123 | cfi_adjust_cfa_offset (-4)		ASM_LINE_SEP	\ | |
| 124 | cfi_restore (blink)			ASM_LINE_SEP	\ | |
| 125 | j_s [blink] | |
| 126 | ||
| 127 | # define DO_CALL(syscall_name, args)			\ | |
| 128 | mov r8, __NR_##syscall_name	ASM_LINE_SEP	\ | |
| 129 | ARC_TRAP_INSN			ASM_LINE_SEP | |
| 130 | ||
| 131 | # define ARC_TRAP_INSN	trap_s 0 | |
| 132 | ||
| 133 | #else /* !__ASSEMBLER__ */ | |
| 134 | ||
| 135 | # define SINGLE_THREAD_BY_GLOBAL		1 | |
| 136 | ||
| 137 | # if IS_IN (libc) | |
| 138 | extern long int __syscall_error (long int); | |
| 139 | hidden_proto (__syscall_error) | |
| 140 | # endif | |
| 141 | ||
| 142 | # define ARC_TRAP_INSN	"trap_s 0	\n\t" | |
| 143 | ||
| 144 | # undef INTERNAL_SYSCALL_NCS | |
| 145 | # define INTERNAL_SYSCALL_NCS(number, nr_args, args...)	\ | |
| 146 | ({								\ | |
| 147 | /* Per ABI, r0 is 1st arg and return reg. */		\ | |
| 148 | register long int __ret __asm__("r0");			\ | |
| 149 | register long int _sys_num __asm__("r8");			\ | |
| 150 | 								\ | |
| 151 | LOAD_ARGS_##nr_args (number, args)				\ | |
| 152 | 								\ | |
| 153 | __asm__ volatile (						\ | |
| 154 | ARC_TRAP_INSN				\ | |
| 155 | : "+r" (__ret)				\ | |
| 156 | : "r"(_sys_num) ASM_ARGS_##nr_args	\ | |
| 157 | : "memory");				\ | |
| 158 | \ | |
| 159 | __ret; }) | |
| 160 | ||
| 161 | # undef INTERNAL_SYSCALL | |
| 162 | # define INTERNAL_SYSCALL(name, nr, args...) 	\ | |
| 163 | INTERNAL_SYSCALL_NCS(__NR_##name, nr, args) | |
| 164 | ||
| 165 | /* Macros for setting up inline __asm__ input regs. */ | |
| 166 | # define ASM_ARGS_0 | |
| 167 | # define ASM_ARGS_1	ASM_ARGS_0, "r" (__ret) | |
| 168 | # define ASM_ARGS_2	ASM_ARGS_1, "r" (_arg2) | |
| 169 | # define ASM_ARGS_3	ASM_ARGS_2, "r" (_arg3) | |
| 170 | # define ASM_ARGS_4	ASM_ARGS_3, "r" (_arg4) | |
| 171 | # define ASM_ARGS_5	ASM_ARGS_4, "r" (_arg5) | |
| 172 | # define ASM_ARGS_6	ASM_ARGS_5, "r" (_arg6) | |
| 173 | # define ASM_ARGS_7	ASM_ARGS_6, "r" (_arg7) | |
| 174 | ||
| 175 | /* Macros for converting sys-call wrapper args into sys call args. */ | |
| 176 | # define LOAD_ARGS_0(nm, arg)				\ | |
| 177 | _sys_num = (long int) (nm); | |
| 178 | ||
| 179 | # define LOAD_ARGS_1(nm, arg1)				\ | |
| 180 | __ret = (long int) (arg1);					\ | |
| 181 | LOAD_ARGS_0 (nm, arg1) | |
| 182 | ||
| 183 | /* Note that the use of _tmpX might look superflous, however it is needed | |
| 184 | to ensure that register variables are not clobbered if arg happens to be | |
| 185 | a function call itself. e.g. sched_setaffinity() calling getpid() for arg2 | |
| 186 | Also this specific order of recursive calling is important to segregate | |
| 187 | the tmp args evaluation (function call case described above) and assigment | |
| 188 | of register variables. */ | |
| 189 | ||
| 190 | # define LOAD_ARGS_2(nm, arg1, arg2)			\ | |
| 191 | long int _tmp2 = (long int) (arg2);			\ | |
| 192 | LOAD_ARGS_1 (nm, arg1)				\ | |
| 193 | register long int _arg2 __asm__ ("r1") = _tmp2; | |
| 194 | ||
| 195 | # define LOAD_ARGS_3(nm, arg1, arg2, arg3)		\ | |
| 196 | long int _tmp3 = (long int) (arg3);			\ | |
| 197 | LOAD_ARGS_2 (nm, arg1, arg2)				\ | |
| 198 | register long int _arg3 __asm__ ("r2") = _tmp3; | |
| 199 | ||
| 200 | #define LOAD_ARGS_4(nm, arg1, arg2, arg3, arg4)		\ | |
| 201 | long int _tmp4 = (long int) (arg4);			\ | |
| 202 | LOAD_ARGS_3 (nm, arg1, arg2, arg3)			\ | |
| 203 | register long int _arg4 __asm__ ("r3") = _tmp4; | |
| 204 | ||
| 205 | # define LOAD_ARGS_5(nm, arg1, arg2, arg3, arg4, arg5)	\ | |
| 206 | long int _tmp5 = (long int) (arg5);			\ | |
| 207 | LOAD_ARGS_4 (nm, arg1, arg2, arg3, arg4)		\ | |
| 208 | register long int _arg5 __asm__ ("r4") = _tmp5; | |
| 209 | ||
| 210 | # define LOAD_ARGS_6(nm, arg1, arg2, arg3, arg4, arg5, arg6)\ | |
| 211 | long int _tmp6 = (long int) (arg6);			\ | |
| 212 | LOAD_ARGS_5 (nm, arg1, arg2, arg3, arg4, arg5)	\ | |
| 213 | register long int _arg6 __asm__ ("r5") = _tmp6; | |
| 214 | ||
| 215 | # define LOAD_ARGS_7(nm, arg1, arg2, arg3, arg4, arg5, arg6, arg7)\ | |
| 216 | long int _tmp7 = (int) (arg7);				\ | |
| 217 | LOAD_ARGS_6 (nm, arg1, arg2, arg3, arg4, arg5, arg6)	\ | |
| 218 | register long int _arg7 __asm__ ("r6") = _tmp7; | |
| 219 | ||
| 220 | /* Pointer mangling not yet supported. */ | |
| 221 | # define PTR_MANGLE(var) (void) (var) | |
| 222 | # define PTR_DEMANGLE(var) (void) (var) | |
| 223 | ||
| 224 | # undef HAVE_INTERNAL_BRK_ADDR_SYMBOL | |
| 225 | # define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1 | |
| 226 | ||
| 227 | #endif /* !__ASSEMBLER__ */ | |
| 228 | ||
| 229 | #endif /* linux/arc/sysdep.h */ |
lib/libc/glibc/sysdeps/unix/sysv/linux/csky/sysdep.h created+515| ... | ... | @@ -0,0 +1,515 @@ |
| 1 | /* Assembly macros for C-SKY. | |
| 2 | Copyright (C) 2018-2021 Free Software Foundation, Inc. | |
| 3 | This file is part of the GNU C Library. | |
| 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | |
| 6 | modify it under the terms of the GNU Lesser General Public | |
| 7 | License as published by the Free Software Foundation; either | |
| 8 | version 2.1 of the License, or (at your option) any later version. | |
| 9 | ||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 13 | Lesser General Public License for more details. | |
| 14 | ||
| 15 | You should have received a copy of the GNU Lesser General Public | |
| 16 | License along with the GNU C Library. If not, see | |
| 17 | <https://www.gnu.org/licenses/>. */ | |
| 18 | ||
| 19 | #ifndef _LINUX_CSKY_SYSDEP_H | |
| 20 | #define _LINUX_CSKY_SYSDEP_H 1 | |
| 21 | ||
| 22 | /* There is some commonality. */ | |
| 23 | #include <sysdeps/unix/sysv/linux/generic/sysdep.h> | |
| 24 | #include <sysdeps/unix/sysv/linux/sysdep.h> | |
| 25 | #include <sysdeps/csky/sysdep.h> | |
| 26 | ||
| 27 | /* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO. */ | |
| 28 | #include <dl-sysdep.h> | |
| 29 | ||
| 30 | #include <tls.h> | |
| 31 | ||
| 32 | /* In order to get __set_errno() definition in INLINE_SYSCALL. */ | |
| 33 | #ifndef __ASSEMBLER__ | |
| 34 | # include <errno.h> | |
| 35 | #endif | |
| 36 | ||
| 37 | #undef SYS_ify | |
| 38 | #define SYS_ify(syscall_name) (__NR_##syscall_name) | |
| 39 | ||
| 40 | #ifdef __ASSEMBLER__ | |
| 41 | /* Linux uses a negative return value to indicate syscall errors, | |
| 42 | unlike most Unices, which use the condition codes' carry flag. | |
| 43 | ||
| 44 | Since version 2.1 the return value of a system call might be | |
| 45 | negative even if the call succeeded. E.g., the `lseek' system call | |
| 46 | might return a large offset. Therefore we must not anymore test | |
| 47 | for < 0, but test for a real error by making sure the value in R0 | |
| 48 | is a real error number. Linus said he will make sure the no syscall | |
| 49 | returns a value in -1 .. -4095 as a valid result so we can safely | |
| 50 | test with -4095. */ | |
| 51 | ||
| 52 | # undef PSEUDO | |
| 53 | # define PSEUDO(name, syscall_name, args)	\ | |
| 54 | .text;					\ | |
| 55 | ENTRY (name);					\ | |
| 56 | DO_CALL (syscall_name, args); | |
| 57 | ||
| 58 | # define GETGB				\ | |
| 59 | 	grs	t0, .Lgetpc;		\ | |
| 60 | .Lgetpc:				\ | |
| 61 | 	lrw	gb, .Lgetpc@GOTPC;	\ | |
| 62 | 	addu	gb, t0; | |
| 63 | ||
| 64 | # if IS_IN (libc) | |
| 65 | # ifdef __PIC__ | |
| 66 | # define PSEUDO_RET			\ | |
| 67 | 	btsti	a0, 31;			\ | |
| 68 | 	bf	1f;			\ | |
| 69 | 	subi	sp, 8;			\ | |
| 70 | 	st.w	lr, (sp);		\ | |
| 71 | 	st.w	gb, (sp, 4);		\ | |
| 72 | 	GETGB;				\ | |
| 73 | 	lrw	a2, SYSCALL_ERROR@PLT;	\ | |
| 74 | 	add	a2, gb;			\ | |
| 75 | 	ld.w	a2, (a2);		\ | |
| 76 | 	jsr	a2;			\ | |
| 77 | 	ld.w	lr, (sp);		\ | |
| 78 | 	ld.w	gb, (sp, 4);		\ | |
| 79 | 	addi	sp, 8;			\ | |
| 80 | 1:					\ | |
| 81 | 	rts | |
| 82 | # else | |
| 83 | # define PSEUDO_RET			\ | |
| 84 | 	btsti	a0, 31;			\ | |
| 85 | 	bf	1f;			\ | |
| 86 | 	jmpi	SYSCALL_ERROR;		\ | |
| 87 | 1:					\ | |
| 88 | 	rts | |
| 89 | # endif | |
| 90 | # else | |
| 91 | # ifdef __PIC__ | |
| 92 | # define PSEUDO_RET			\ | |
| 93 | 	btsti	a0, 31;			\ | |
| 94 | 	bf	1f;			\ | |
| 95 | 	subi	sp, 8;			\ | |
| 96 | 	st.w	lr, (sp);		\ | |
| 97 | 	st.w	gb, (sp, 4);		\ | |
| 98 | 	GETGB;				\ | |
| 99 | 	bsr	SYSCALL_ERROR;		\ | |
| 100 | 	ld.w	lr, (sp);		\ | |
| 101 | 	ld.w	gb, (sp, 4);		\ | |
| 102 | 	addi	sp, 8;			\ | |
| 103 | 1:					\ | |
| 104 | 	rts | |
| 105 | # else | |
| 106 | # define PSEUDO_RET			\ | |
| 107 | 	btsti	a0, 31;			\ | |
| 108 | 	bt	SYSCALL_ERROR;		\ | |
| 109 | 	rts | |
| 110 | # endif | |
| 111 | # endif | |
| 112 | ||
| 113 | # undef ret | |
| 114 | # define ret PSEUDO_RET | |
| 115 | ||
| 116 | # undef PSEUDO_END | |
| 117 | # define PSEUDO_END(name)		\ | |
| 118 | .align 4;				\ | |
| 119 | SYSCALL_ERROR_HANDLER;		\ | |
| 120 | END (name) | |
| 121 | ||
| 122 | # undef PSEUDO_NOERRNO | |
| 123 | # define PSEUDO_NOERRNO(name, syscall_name, args)	\ | |
| 124 | .text;						\ | |
| 125 | ENTRY (name);						\ | |
| 126 | DO_CALL (syscall_name, args) | |
| 127 | ||
| 128 | # define PSEUDO_RET_NOERRNO rts | |
| 129 | ||
| 130 | # undef ret_NOERRNO | |
| 131 | # define ret_NOERRNO PSEUDO_RET_NOERRNO | |
| 132 | ||
| 133 | # undef PSEUDO_END_NOERRNO | |
| 134 | # define PSEUDO_END_NOERRNO(name) END (name) | |
| 135 | ||
| 136 | /* The function has to return the error code. */ | |
| 137 | # undef PSEUDO_ERRVAL | |
| 138 | # define PSEUDO_ERRVAL(name, syscall_name, args)	\ | |
| 139 | .text;						\ | |
| 140 | ENTRY (name)						\ | |
| 141 | DO_CALL (syscall_name, args);				\ | |
| 142 | not	a0;						\ | |
| 143 | addi	a0, 1 | |
| 144 | ||
| 145 | # undef PSEUDO_END_ERRVAL | |
| 146 | # define PSEUDO_END_ERRVAL(name) END (name) | |
| 147 | ||
| 148 | # define ret_ERRVAL rts | |
| 149 | ||
| 150 | # if !IS_IN (libc) | |
| 151 | # define SYSCALL_ERROR __local_syscall_error | |
| 152 | # if RTLD_PRIVATE_ERRNO | |
| 153 | # ifdef __PIC__ | |
| 154 | # define SYSCALL_ERROR_HANDLER	\ | |
| 155 | __local_syscall_error:			\ | |
| 156 | 	lrw	a1, rtld_errno@PLT; 	\ | |
| 157 | 	addu	a1, gb;			\ | |
| 158 | 	ldw	a1, (a1);		\ | |
| 159 | 	rsubi	a0, 0;			\ | |
| 160 | 	stw	a0, (a1);		\ | |
| 161 | 	bmaski	a0, 0;			\ | |
| 162 | 	rts | |
| 163 | # else /* __PIC__ */ | |
| 164 | # define SYSCALL_ERROR_HANDLER	\ | |
| 165 | __local_syscall_error:			\ | |
| 166 | 	lrw	a1, rtld_errno;		\ | |
| 167 | 	rsubi	a0, 0;			\ | |
| 168 | 	stw	a0, (a1);		\ | |
| 169 | 	bmaski	a0, 0;			\ | |
| 170 | 	rts | |
| 171 | # endif /* __PIC__ */ | |
| 172 | # else /* !RTLD_PRIVATE_ERRNO */ | |
| 173 | # ifdef __PIC__ | |
| 174 | # define SYSCALL_ERROR_HANDLER		\ | |
| 175 | __local_syscall_error:				\ | |
| 176 | 	subi	sp, 8;				\ | |
| 177 | 	stw	a0, (sp, 0);			\ | |
| 178 | 	stw	r15, (sp, 4);			\ | |
| 179 | 	lrw	a1, __errno_location@PLT;	\ | |
| 180 | 	add	a1, gb;				\ | |
| 181 | 	ldw	a1, (a1);			\ | |
| 182 | 	jsr	a1;				\ | |
| 183 | 	ldw	a1, (sp, 0); /* load errno*/	\ | |
| 184 | 	ldw	r15, (sp, 4);			\ | |
| 185 | 	addi	sp, 8;				\ | |
| 186 | 	movi	a2, 0;				\ | |
| 187 | 	rsub	a1, a1, a2;			\ | |
| 188 | 	stw	a1, (a0);			\ | |
| 189 | 	bmaski	a0, 0;				\ | |
| 190 | 	rts | |
| 191 | # else | |
| 192 | # define SYSCALL_ERROR_HANDLER 		\ | |
| 193 | __local_syscall_error:				\ | |
| 194 | 	subi	sp, 8;				\ | |
| 195 | 	stw	a0, (sp, 0);			\ | |
| 196 | 	stw	r15, (sp, 4);			\ | |
| 197 | 	lrw	a1, __errno_location;		\ | |
| 198 | 	jsr	a1;				\ | |
| 199 | 	ldw	a1, (sp, 0); /* load errno */	\ | |
| 200 | 	ldw	r15, (sp, 4);			\ | |
| 201 | 	addi	sp, 8;				\ | |
| 202 | 	movi	a2, 0;				\ | |
| 203 | 	rsub	a1, a1, a2;			\ | |
| 204 | 	stw	a1, (a0);			\ | |
| 205 | 	bmaski	a0, 0;				\ | |
| 206 | 	rts | |
| 207 | # endif /* __PIC__ */ | |
| 208 | # endif/* RTLD_PRIVATE_ERROR */ | |
| 209 | # else | |
| 210 | # define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */ | |
| 211 | # define SYSCALL_ERROR __syscall_error | |
| 212 | # endif/* IS_IN (libc) */ | |
| 213 | ||
| 214 | /* define DO_CALL */ | |
| 215 | # undef DO_CALL | |
| 216 | # define DO_CALL(syscall_name, args)	\ | |
| 217 | DOARGS_##args;			\ | |
| 218 | lrw	r7, SYS_ify(syscall_name);	\ | |
| 219 | trap	0;				\ | |
| 220 | UNDOARGS_##args | |
| 221 | ||
| 222 | # undef DOARGS_0 | |
| 223 | # define DOARGS_0			\ | |
| 224 | 	subi	sp, 8;			\ | |
| 225 | 	cfi_adjust_cfa_offset (8);	\ | |
| 226 | 	stw	r7, (sp, 0);		\ | |
| 227 | 	cfi_rel_offset (r7, 0); | |
| 228 | ||
| 229 | # undef DOARGS_1 | |
| 230 | # define DOARGS_1 DOARGS_0 | |
| 231 | # undef DOARGS_2 | |
| 232 | # define DOARGS_2 DOARGS_0 | |
| 233 | # undef DOARGS_3 | |
| 234 | # define DOARGS_3 DOARGS_0 | |
| 235 | # undef DOARGS_4 | |
| 236 | # define DOARGS_4 DOARGS_0 | |
| 237 | # undef DOARGS_5 | |
| 238 | # define DOARGS_5			\ | |
| 239 | 	subi	sp, 8;			\ | |
| 240 | 	cfi_adjust_cfa_offset (8);	\ | |
| 241 | 	stw	r7, (sp, 0);		\ | |
| 242 | 	cfi_rel_offset (7, 0);		\ | |
| 243 | 	stw	r4, (sp, 4);		\ | |
| 244 | 	cfi_rel_offset (4, 4);		\ | |
| 245 | 	ldw	r4, (sp, 8) | |
| 246 | # undef DOARGS_6 | |
| 247 | # define DOARGS_6			\ | |
| 248 | 	subi	sp, 16;			\ | |
| 249 | 	cfi_adjust_cfa_offset (16);	\ | |
| 250 | 	stw	r7, (sp, 0);		\ | |
| 251 | 	cfi_rel_offset (7, 0);		\ | |
| 252 | 	stw	r4, (sp, 4);		\ | |
| 253 | 	cfi_rel_offset (4, 4);		\ | |
| 254 | 	stw	r5, (sp, 8);		\ | |
| 255 | 	cfi_rel_offset (5, 8);		\ | |
| 256 | 	ldw	r4, (sp, 16);		\ | |
| 257 | 	ldw	r5, (sp, 20) | |
| 258 | ||
| 259 | # undef UNDOARGS_0 | |
| 260 | # define UNDOARGS_0 \ | |
| 261 | ldw r7, (sp, 0); \ | |
| 262 | cfi_restore (r7); \ | |
| 263 | addi sp, 8; \ | |
| 264 | cfi_adjust_cfa_offset (-8); | |
| 265 | ||
| 266 | # undef UNDOARGS_1 | |
| 267 | # define UNDOARGS_1 UNDOARGS_0 | |
| 268 | # undef UNDOARGS_2 | |
| 269 | # define UNDOARGS_2 UNDOARGS_0 | |
| 270 | # undef UNDOARGS_3 | |
| 271 | # define UNDOARGS_3 UNDOARGS_0 | |
| 272 | # undef UNDOARGS_4 | |
| 273 | # define UNDOARGS_4 UNDOARGS_0 | |
| 274 | # undef UNDOARGS_5 | |
| 275 | # define UNDOARGS_5			\ | |
| 276 | 	ldw	r7, (sp, 0);		\ | |
| 277 | 	cfi_restore (r4);		\ | |
| 278 | 	ldw	r4, (sp, 4);		\ | |
| 279 | 	cfi_restore (r4);		\ | |
| 280 | 	addi	sp, 8;			\ | |
| 281 | 	cfi_adjust_cfa_offset (-8); | |
| 282 | ||
| 283 | # undef UNDOARGS_6 | |
| 284 | # define UNDOARGS_6			\ | |
| 285 | 	ldw	r7, (sp, 0);		\ | |
| 286 | 	cfi_restore (r7);		\ | |
| 287 | 	ldw	r4, (sp, 4);		\ | |
| 288 | 	cfi_restore (r4);		\ | |
| 289 | 	ldw	r5, (sp, 8);		\ | |
| 290 | 	cfi_restore (r5);		\ | |
| 291 | 	addi	sp, 16;			\ | |
| 292 | 	cfi_adjust_cfa_offset (-16); | |
| 293 | ||
| 294 | #else /* not __ASSEMBLER__ */ | |
| 295 | ||
| 296 | # undef INTERNAL_SYSCALL_RAW | |
| 297 | # define INTERNAL_SYSCALL_RAW0(name, dummy...)				\ | |
| 298 | ({unsigned int __sys_result;						\ | |
| 299 | {									\ | |
| 300 | register int _a1 __asm__ ("a0"), _nr __asm__ ("r7");		\ | |
| 301 | _nr = name;							\ | |
| 302 | __asm__ __volatile__ ("trap 0 \n\t"				\ | |
| 303 | 			 : "=r" (_a1)				\ | |
| 304 | 			 : "r" (_nr)				\ | |
| 305 | 			 : "memory");				\ | |
| 306 | 	 __sys_result = _a1;					\ | |
| 307 | }									\ | |
| 308 | (int) __sys_result; }) | |
| 309 | ||
| 310 | # define INTERNAL_SYSCALL_RAW1(name, arg1)				\ | |
| 311 | ({unsigned int __sys_result;						\ | |
| 312 | register int _tmp_arg1 = (int)(arg1);				\ | |
| 313 | {									\ | |
| 314 | register int _a1 __asm__ ("a0"), _nr __asm__ ("r7");		\ | |
| 315 | _a1 = _tmp_arg1;							\ | |
| 316 | _nr = name;							\ | |
| 317 | __asm__ __volatile__ ("trap 0 \n\t"				\ | |
| 318 | 			 : "=r" (_a1)				\ | |
| 319 | 			 : "r" (_nr), "r" (_a1)			\ | |
| 320 | 			 : "memory");				\ | |
| 321 | 	 __sys_result = _a1;					\ | |
| 322 | }									\ | |
| 323 | (int) __sys_result; }) | |
| 324 | ||
| 325 | # define INTERNAL_SYSCALL_RAW2(name, arg1, arg2)			\ | |
| 326 | ({unsigned int __sys_result;						\ | |
| 327 | register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2);	\ | |
| 328 | {									\ | |
| 329 | register int _nr __asm__ ("r7");					\ | |
| 330 | register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1");		\ | |
| 331 | _a1 = _tmp_arg1, _a2 = _tmp_arg2;				\ | |
| 332 | _nr = name;							\ | |
| 333 | __asm__ __volatile__ ("trap 0 \n\t"				\ | |
| 334 | 			 : "=r" (_a1)				\ | |
| 335 | 			 : "r" (_nr), "r" (_a1), "r" (_a2)		\ | |
| 336 | 			 : "memory");				\ | |
| 337 | 	 __sys_result = _a1;					\ | |
| 338 | }									\ | |
| 339 | (int) __sys_result; }) | |
| 340 | ||
| 341 | # define INTERNAL_SYSCALL_RAW3(name, arg1, arg2, arg3)			\ | |
| 342 | ({unsigned int __sys_result;						\ | |
| 343 | register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2);	\ | |
| 344 | register int _tmp_arg3 = (int)(arg3);				\ | |
| 345 | {									\ | |
| 346 | register int _nr __asm__ ("r7");					\ | |
| 347 | register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1");		\ | |
| 348 | register int _a3 __asm__ ("a2");					\ | |
| 349 | _a1 = _tmp_arg1;							\ | |
| 350 | _a2 = _tmp_arg2;							\ | |
| 351 | _a3 = _tmp_arg3;							\ | |
| 352 | _nr = name;							\ | |
| 353 | __asm__ __volatile__ ("trap 0 \n\t"				\ | |
| 354 | 			 : "=r" (_a1)				\ | |
| 355 | 			 : "r" (_nr), "r" (_a1), "r" (_a2),		\ | |
| 356 | 			 "r" (_a3)				\ | |
| 357 | 			 : "memory");				\ | |
| 358 | 	 __sys_result = _a1;					\ | |
| 359 | }									\ | |
| 360 | (int) __sys_result; }) | |
| 361 | ||
| 362 | # define INTERNAL_SYSCALL_RAW4(name, arg1, arg2, arg3, arg4)		\ | |
| 363 | ({unsigned int __sys_result;						\ | |
| 364 | register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2);	\ | |
| 365 | register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4);	\ | |
| 366 | {									\ | |
| 367 | register int _nr __asm__ ("r7");					\ | |
| 368 | register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1");		\ | |
| 369 | register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3");		\ | |
| 370 | _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3;		\ | |
| 371 | _a4 = _tmp_arg4;							\ | |
| 372 | _nr = name;							\ | |
| 373 | __asm__ __volatile__ ("trap 0 \n\t"				\ | |
| 374 | 			 : "=r" (_a1)				\ | |
| 375 | 			 : "r" (_nr), "r" (_a1), "r" (_a2),		\ | |
| 376 | 			 "r" (_a3), "r" (_a4)			\ | |
| 377 | 			 : "memory");				\ | |
| 378 | 	 __sys_result = _a1;					\ | |
| 379 | }									\ | |
| 380 | (int) __sys_result; }) | |
| 381 | ||
| 382 | # define INTERNAL_SYSCALL_RAW5(name, arg1, arg2, arg3, arg4,		\ | |
| 383 | 			 arg5)					\ | |
| 384 | ({unsigned int __sys_result;						\ | |
| 385 | register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2);	\ | |
| 386 | register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4);	\ | |
| 387 | register int _tmp_arg5 = (int)(arg5);				\ | |
| 388 | {									\ | |
| 389 | register int _nr __asm__ ("r7");					\ | |
| 390 | register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1");		\ | |
| 391 | register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3");		\ | |
| 392 | register int _a5 __asm__ ("r4");					\ | |
| 393 | _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3;		\ | |
| 394 | _a4 = _tmp_arg4, _a5 = _tmp_arg5;				\ | |
| 395 | _nr = name;							\ | |
| 396 | __asm__ __volatile__ ("trap 0 \n\t"				\ | |
| 397 | 			 : "=r" (_a1)				\ | |
| 398 | 			 : "r" (_nr), "r" (_a1), "r" (_a2),		\ | |
| 399 | 			 "r" (_a3), "r" (_a4), "r" (_a5)		\ | |
| 400 | 			 : "memory");				\ | |
| 401 | 	 __sys_result = _a1;					\ | |
| 402 | }									\ | |
| 403 | (int) __sys_result; }) | |
| 404 | ||
| 405 | # define INTERNAL_SYSCALL_RAW6(name, arg1, arg2, arg3, arg4,		\ | |
| 406 | 			 arg5, arg6)				\ | |
| 407 | ({unsigned int __sys_result;						\ | |
| 408 | register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2);	\ | |
| 409 | register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4);	\ | |
| 410 | register int _tmp_arg5 = (int)(arg5), _tmp_arg6 = (int)(arg6);	\ | |
| 411 | {									\ | |
| 412 | register int _nr __asm__ ("r7");					\ | |
| 413 | register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1");		\ | |
| 414 | register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3");		\ | |
| 415 | register int _a5 __asm__ ("r4"), _a6 __asm__ ("r5");		\ | |
| 416 | _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3;		\ | |
| 417 | _a4 = _tmp_arg4, _a5 = _tmp_arg5, _a6 = _tmp_arg6;		\ | |
| 418 | _nr = name;							\ | |
| 419 | __asm__ __volatile__ ("trap 0 \n\t"				\ | |
| 420 | 			 : "=r" (_a1)				\ | |
| 421 | 			 : "r" (_nr), "r" (_a1), "r" (_a2),		\ | |
| 422 | 			 "r" (_a3), "r" (_a4), "r" (_a5),		\ | |
| 423 | 			 "r" (_a6)				\ | |
| 424 | 			 : "memory");				\ | |
| 425 | 	 __sys_result = _a1;					\ | |
| 426 | }									\ | |
| 427 | (int) __sys_result; }) | |
| 428 | ||
| 429 | # define INTERNAL_SYSCALL_RAW7(name, arg1, arg2, arg3, arg4,		\ | |
| 430 | 			 arg5, arg6, arg7)				\ | |
| 431 | ({unsigned int __sys_result;						\ | |
| 432 | register int _tmp_arg1 = (int)(arg1), _tmp_arg2 = (int)(arg2);	\ | |
| 433 | register int _tmp_arg3 = (int)(arg3), _tmp_arg4 = (int)(arg4);	\ | |
| 434 | register int _tmp_arg5 = (int)(arg5), _tmp_arg6 = (int)(arg6);	\ | |
| 435 | register int _tmp_arg7 = (int)(arg7);				\ | |
| 436 | {									\ | |
| 437 | register int _nr __asm__ ("r7");					\ | |
| 438 | register int _a1 __asm__ ("a0"), _a2 __asm__ ("a1");		\ | |
| 439 | register int _a3 __asm__ ("a2"), _a4 __asm__ ("a3");		\ | |
| 440 | register int _a5 __asm__ ("r4"), _a6 __asm__ ("r5");		\ | |
| 441 | register int _a7 __asm__ ("r6");					\ | |
| 442 | _a1 = _tmp_arg1, _a2 = _tmp_arg2, _a3 = _tmp_arg3;		\ | |
| 443 | _a4 = _tmp_arg4, _a5 = _tmp_arg5, _a6 = _tmp_arg6;		\ | |
| 444 | _a7 = _tmp_arg7;							\ | |
| 445 | _nr = name;							\ | |
| 446 | __asm__ __volatile__ ("trap 0 \n\t"				\ | |
| 447 | 			 : "=r" (_a1)				\ | |
| 448 | 			 : "r" (_nr), "r" (_a1), "r" (_a2),		\ | |
| 449 | 			 "r" (_a3), "r" (_a4), "r" (_a5),		\ | |
| 450 | 			 "r" (_a6), "r" (_a7)			\ | |
| 451 | 			 : "memory");				\ | |
| 452 | 	 __sys_result = _a1;					\ | |
| 453 | }									\ | |
| 454 | (int) __sys_result; }) | |
| 455 | ||
| 456 | # undef INTERNAL_SYSCALL | |
| 457 | # define INTERNAL_SYSCALL(name, nr, args...)			\ | |
| 458 | INTERNAL_SYSCALL_RAW##nr(SYS_ify(name), args) | |
| 459 | ||
| 460 | # undef INTERNAL_SYSCALL_NCS | |
| 461 | # define INTERNAL_SYSCALL_NCS(number, nr, args...)		\ | |
| 462 | INTERNAL_SYSCALL_RAW##nr (number, args) | |
| 463 | ||
| 464 | #undef HAVE_INTERNAL_BRK_ADDR_SYMBOL | |
| 465 | #define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1 | |
| 466 | ||
| 467 | #endif /* __ASSEMBLER__ */ | |
| 468 | ||
| 469 | /* Pointer mangling support. */ | |
| 470 | #if (IS_IN (rtld) \ | |
| 471 | || (!defined SHARED && (IS_IN (libc) || IS_IN (libpthread)))) | |
| 472 | # ifdef __ASSEMBLER__ | |
| 473 | # define PTR_MANGLE(dst, src, guard)			\ | |
| 474 | 	grs	t0, 1f;					\ | |
| 475 | 1:							\ | |
| 476 | 	lrw	guard, 1b@GOTPC;			\ | |
| 477 | 	addu	t0, guard;				\ | |
| 478 | 	lrw	guard, __pointer_chk_guard_local@GOT;	\ | |
| 479 | 	ldr.w	guard, (t0, guard << 0);		\ | |
| 480 | 	ldw	guard, (guard, 0);			\ | |
| 481 | 	xor	dst, src, guard; | |
| 482 | # define PTR_DEMANGLE(dst, src, guard) PTR_MANGLE (dst, src, guard) | |
| 483 | # define PTR_MANGLE2(dst, src, guard) \ | |
| 484 | 	xor	dst, src, guard | |
| 485 | # define PTR_DEMANGLE2(dst, src, guard) PTR_MANGLE2 (dst, src, guard) | |
| 486 | # else | |
| 487 | extern uintptr_t __pointer_chk_guard_local; | |
| 488 | # define PTR_MANGLE(var) \ | |
| 489 | (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) | |
| 490 | # define PTR_DEMANGLE(var) PTR_MANGLE (var) | |
| 491 | # endif | |
| 492 | #else | |
| 493 | # ifdef __ASSEMBLER__ | |
| 494 | # define PTR_MANGLE(dst, src, guard)		\ | |
| 495 | 	grs	t0, 1f;				\ | |
| 496 | 1:						\ | |
| 497 | 	lrw	guard, 1b@GOTPC;		\ | |
| 498 | 	addu	t0, guard;			\ | |
| 499 | 	lrw	guard, __pointer_chk_guard@GOT;	\ | |
| 500 | 	ldr.w	guard, (t0, guard << 0);	\ | |
| 501 | 	ldw	guard, (guard, 0);		\ | |
| 502 | 	xor	dst, src, guard; | |
| 503 | # define PTR_DEMANGLE(dst, src, guard) PTR_MANGLE (dst, src, guard) | |
| 504 | # define PTR_MANGLE2(dst, src, guard) \ | |
| 505 | 	xor	dst, src, guard | |
| 506 | # define PTR_DEMANGLE2(dst, src, guard) PTR_MANGLE2 (dst, src, guard) | |
| 507 | # else | |
| 508 | extern uintptr_t __pointer_chk_guard; | |
| 509 | # define PTR_MANGLE(var) \ | |
| 510 | (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) | |
| 511 | # define PTR_DEMANGLE(var) PTR_MANGLE (var) | |
| 512 | # endif | |
| 513 | #endif | |
| 514 | ||
| 515 | #endif /* linux/csky/sysdep.h */ |
lib/libc/glibc/sysdeps/unix/sysv/linux/mips/mips64/sysdep.h created+307| ... | ... | @@ -0,0 +1,307 @@ |
| 1 | /* Copyright (C) 2000-2021 Free Software Foundation, Inc. | |
| 2 | This file is part of the GNU C Library. | |
| 3 | ||
| 4 | The GNU C Library is free software; you can redistribute it and/or | |
| 5 | modify it under the terms of the GNU Lesser General Public | |
| 6 | License as published by the Free Software Foundation; either | |
| 7 | version 2.1 of the License, or (at your option) any later version. | |
| 8 | ||
| 9 | The GNU C Library is distributed in the hope that it will be useful, | |
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 12 | Lesser General Public License for more details. | |
| 13 | ||
| 14 | You should have received a copy of the GNU Lesser General Public | |
| 15 | License along with the GNU C Library. If not, see | |
| 16 | <https://www.gnu.org/licenses/>. */ | |
| 17 | ||
| 18 | #ifndef _LINUX_MIPS_SYSDEP_H | |
| 19 | #define _LINUX_MIPS_SYSDEP_H 1 | |
| 20 | ||
| 21 | /* There is some commonality. */ | |
| 22 | #include <sysdeps/unix/sysv/linux/mips/sysdep.h> | |
| 23 | #include <sysdeps/unix/sysv/linux/sysdep.h> | |
| 24 | #include <sysdeps/unix/mips/mips64/sysdep.h> | |
| 25 | ||
| 26 | #include <tls.h> | |
| 27 | ||
| 28 | /* For Linux we can use the system call table in the header file | |
| 29 | 	/usr/include/asm/unistd.h | |
| 30 | of the kernel. But these symbols do not follow the SYS_* syntax | |
| 31 | so we have to redefine the `SYS_ify' macro here. */ | |
| 32 | #undef SYS_ify | |
| 33 | #define SYS_ify(syscall_name)	__NR_##syscall_name | |
| 34 | ||
| 35 | #ifdef __ASSEMBLER__ | |
| 36 | ||
| 37 | /* We don't want the label for the error handler to be visible in the symbol | |
| 38 | table when we define it here. */ | |
| 39 | # undef SYSCALL_ERROR_LABEL | |
| 40 | # define SYSCALL_ERROR_LABEL 99b | |
| 41 | ||
| 42 | #else /* ! __ASSEMBLER__ */ | |
| 43 | ||
| 44 | #undef HAVE_INTERNAL_BRK_ADDR_SYMBOL | |
| 45 | #define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1 | |
| 46 | ||
| 47 | #if _MIPS_SIM == _ABIN32 | |
| 48 | /* Convert X to a long long, without losing any bits if it is one | |
| 49 | already or warning if it is a 32-bit pointer. */ | |
| 50 | # define ARGIFY(X) ((long long int) (__typeof__ ((X) - (X))) (X)) | |
| 51 | typedef long long int __syscall_arg_t; | |
| 52 | #else | |
| 53 | # define ARGIFY(X) ((long int) (X)) | |
| 54 | typedef long int __syscall_arg_t; | |
| 55 | #endif | |
| 56 | ||
| 57 | /* Note that the original Linux syscall restart convention required the | |
| 58 | instruction immediately preceding SYSCALL to initialize $v0 with the | |
| 59 | syscall number. Then if a restart triggered, $v0 would have been | |
| 60 | clobbered by the syscall interrupted, and needed to be reinititalized. | |
| 61 | The kernel would decrement the PC by 4 before switching back to the | |
| 62 | user mode so that $v0 had been reloaded before SYSCALL was executed | |
| 63 | again. This implied the place $v0 was loaded from must have been | |
| 64 | preserved across a syscall, e.g. an immediate, static register, stack | |
| 65 | slot, etc. | |
| 66 | ||
| 67 | The convention was relaxed in Linux with a change applied to the kernel | |
| 68 | GIT repository as commit 96187fb0bc30cd7919759d371d810e928048249d, that | |
| 69 | first appeared in the 2.6.36 release. Since then the kernel has had | |
| 70 | code that reloads $v0 upon syscall restart and resumes right at the | |
| 71 | SYSCALL instruction, so no special arrangement is needed anymore. | |
| 72 | ||
| 73 | For backwards compatibility with existing kernel binaries we support | |
| 74 | the old convention by choosing the instruction preceding SYSCALL | |
| 75 | carefully. This also means we have to force a 32-bit encoding of the | |
| 76 | microMIPS MOVE instruction if one is used. */ | |
| 77 | ||
| 78 | #ifdef __mips_micromips | |
| 79 | # define MOVE32 "move32" | |
| 80 | #else | |
| 81 | # define MOVE32 "move" | |
| 82 | #endif | |
| 83 | ||
| 84 | #undef INTERNAL_SYSCALL | |
| 85 | #define INTERNAL_SYSCALL(name, nr, args...)			\ | |
| 86 | 	internal_syscall##nr ("li\t%0, %2\t\t\t# " #name "\n\t",	\ | |
| 87 | 			 "IK" (SYS_ify (name)),			\ | |
| 88 | 			 0, args) | |
| 89 | ||
| 90 | #undef INTERNAL_SYSCALL_NCS | |
| 91 | #define INTERNAL_SYSCALL_NCS(number, nr, args...)			\ | |
| 92 | 	internal_syscall##nr (MOVE32 "\t%0, %2\n\t",			\ | |
| 93 | 			 "r" (__s0),				\ | |
| 94 | 			 number, args) | |
| 95 | ||
| 96 | #define internal_syscall0(v0_init, input, number, dummy...)	\ | |
| 97 | ({									\ | |
| 98 | 	long int _sys_result;						\ | |
| 99 | 									\ | |
| 100 | 	{								\ | |
| 101 | 	register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\ | |
| 102 | 	 = (number);							\ | |
| 103 | 	register __syscall_arg_t __v0 asm ("$2");			\ | |
| 104 | 	register __syscall_arg_t __a3 asm ("$7");			\ | |
| 105 | 	__asm__ volatile (						\ | |
| 106 | 	".set\tnoreorder\n\t"						\ | |
| 107 | 	v0_init								\ | |
| 108 | 	"syscall\n\t"							\ | |
| 109 | 	".set reorder"							\ | |
| 110 | 	: "=r" (__v0), "=r" (__a3)					\ | |
| 111 | 	: input								\ | |
| 112 | 	: __SYSCALL_CLOBBERS);						\ | |
| 113 | 	_sys_result = __a3 != 0 ? -__v0 : __v0;				\ | |
| 114 | 	}								\ | |
| 115 | 	_sys_result;							\ | |
| 116 | }) | |
| 117 | ||
| 118 | #define internal_syscall1(v0_init, input, number, arg1)		\ | |
| 119 | ({									\ | |
| 120 | 	long int _sys_result;						\ | |
| 121 | 									\ | |
| 122 | 	{								\ | |
| 123 | 	__syscall_arg_t _arg1 = ARGIFY (arg1);				\ | |
| 124 | 	register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\ | |
| 125 | 	 = (number);							\ | |
| 126 | 	register __syscall_arg_t __v0 asm ("$2");			\ | |
| 127 | 	register __syscall_arg_t __a0 asm ("$4") = _arg1;		\ | |
| 128 | 	register __syscall_arg_t __a3 asm ("$7");			\ | |
| 129 | 	__asm__ volatile (						\ | |
| 130 | 	".set\tnoreorder\n\t"						\ | |
| 131 | 	v0_init								\ | |
| 132 | 	"syscall\n\t"							\ | |
| 133 | 	".set reorder"							\ | |
| 134 | 	: "=r" (__v0), "=r" (__a3)					\ | |
| 135 | 	: input, "r" (__a0)						\ | |
| 136 | 	: __SYSCALL_CLOBBERS);						\ | |
| 137 | 	_sys_result = __a3 != 0 ? -__v0 : __v0;				\ | |
| 138 | 	}								\ | |
| 139 | 	_sys_result;							\ | |
| 140 | }) | |
| 141 | ||
| 142 | #define internal_syscall2(v0_init, input, number, arg1, arg2)	\ | |
| 143 | ({									\ | |
| 144 | 	long int _sys_result;						\ | |
| 145 | 									\ | |
| 146 | 	{								\ | |
| 147 | 	__syscall_arg_t _arg1 = ARGIFY (arg1);				\ | |
| 148 | 	__syscall_arg_t _arg2 = ARGIFY (arg2);				\ | |
| 149 | 	register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\ | |
| 150 | 	 = (number);							\ | |
| 151 | 	register __syscall_arg_t __v0 asm ("$2");			\ | |
| 152 | 	register __syscall_arg_t __a0 asm ("$4") = _arg1;		\ | |
| 153 | 	register __syscall_arg_t __a1 asm ("$5") = _arg2;		\ | |
| 154 | 	register __syscall_arg_t __a3 asm ("$7");			\ | |
| 155 | 	__asm__ volatile (						\ | |
| 156 | 	".set\tnoreorder\n\t"						\ | |
| 157 | 	v0_init								\ | |
| 158 | 	"syscall\n\t"							\ | |
| 159 | 	".set\treorder"							\ | |
| 160 | 	: "=r" (__v0), "=r" (__a3)					\ | |
| 161 | 	: input, "r" (__a0), "r" (__a1)					\ | |
| 162 | 	: __SYSCALL_CLOBBERS);						\ | |
| 163 | 	_sys_result = __a3 != 0 ? -__v0 : __v0;				\ | |
| 164 | 	}								\ | |
| 165 | 	_sys_result;							\ | |
| 166 | }) | |
| 167 | ||
| 168 | #define internal_syscall3(v0_init, input, number, arg1, arg2, arg3)	\ | |
| 169 | ({									\ | |
| 170 | 	long int _sys_result;						\ | |
| 171 | 									\ | |
| 172 | 	{								\ | |
| 173 | 	__syscall_arg_t _arg1 = ARGIFY (arg1);				\ | |
| 174 | 	__syscall_arg_t _arg2 = ARGIFY (arg2);				\ | |
| 175 | 	__syscall_arg_t _arg3 = ARGIFY (arg3);				\ | |
| 176 | 	register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\ | |
| 177 | 	 = (number);							\ | |
| 178 | 	register __syscall_arg_t __v0 asm ("$2");			\ | |
| 179 | 	register __syscall_arg_t __a0 asm ("$4") = _arg1;		\ | |
| 180 | 	register __syscall_arg_t __a1 asm ("$5") = _arg2;		\ | |
| 181 | 	register __syscall_arg_t __a2 asm ("$6") = _arg3;		\ | |
| 182 | 	register __syscall_arg_t __a3 asm ("$7");			\ | |
| 183 | 	__asm__ volatile (						\ | |
| 184 | 	".set\tnoreorder\n\t"						\ | |
| 185 | 	v0_init								\ | |
| 186 | 	"syscall\n\t"							\ | |
| 187 | 	".set\treorder"							\ | |
| 188 | 	: "=r" (__v0), "=r" (__a3)					\ | |
| 189 | 	: input, "r" (__a0), "r" (__a1), "r" (__a2)			\ | |
| 190 | 	: __SYSCALL_CLOBBERS);						\ | |
| 191 | 	_sys_result = __a3 != 0 ? -__v0 : __v0;				\ | |
| 192 | 	}								\ | |
| 193 | 	_sys_result;							\ | |
| 194 | }) | |
| 195 | ||
| 196 | #define internal_syscall4(v0_init, input, number, arg1, arg2, arg3, 	\ | |
| 197 | 			 arg4)						\ | |
| 198 | ({									\ | |
| 199 | 	long int _sys_result;						\ | |
| 200 | 									\ | |
| 201 | 	{								\ | |
| 202 | 	__syscall_arg_t _arg1 = ARGIFY (arg1);				\ | |
| 203 | 	__syscall_arg_t _arg2 = ARGIFY (arg2);				\ | |
| 204 | 	__syscall_arg_t _arg3 = ARGIFY (arg3);				\ | |
| 205 | 	__syscall_arg_t _arg4 = ARGIFY (arg4);				\ | |
| 206 | 	register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\ | |
| 207 | 	 = (number);							\ | |
| 208 | 	register __syscall_arg_t __v0 asm ("$2");			\ | |
| 209 | 	register __syscall_arg_t __a0 asm ("$4") = _arg1;		\ | |
| 210 | 	register __syscall_arg_t __a1 asm ("$5") = _arg2;		\ | |
| 211 | 	register __syscall_arg_t __a2 asm ("$6") = _arg3;		\ | |
| 212 | 	register __syscall_arg_t __a3 asm ("$7") = _arg4;		\ | |
| 213 | 	__asm__ volatile (						\ | |
| 214 | 	".set\tnoreorder\n\t"						\ | |
| 215 | 	v0_init								\ | |
| 216 | 	"syscall\n\t"							\ | |
| 217 | 	".set\treorder"							\ | |
| 218 | 	: "=r" (__v0), "+r" (__a3)					\ | |
| 219 | 	: input, "r" (__a0), "r" (__a1), "r" (__a2)			\ | |
| 220 | 	: __SYSCALL_CLOBBERS);						\ | |
| 221 | 	_sys_result = __a3 != 0 ? -__v0 : __v0;				\ | |
| 222 | 	}								\ | |
| 223 | 	_sys_result;							\ | |
| 224 | }) | |
| 225 | ||
| 226 | #define internal_syscall5(v0_init, input, number, arg1, arg2, arg3, 	\ | |
| 227 | 			 arg4, arg5)					\ | |
| 228 | ({									\ | |
| 229 | 	long int _sys_result;						\ | |
| 230 | 									\ | |
| 231 | 	{								\ | |
| 232 | 	__syscall_arg_t _arg1 = ARGIFY (arg1);				\ | |
| 233 | 	__syscall_arg_t _arg2 = ARGIFY (arg2);				\ | |
| 234 | 	__syscall_arg_t _arg3 = ARGIFY (arg3);				\ | |
| 235 | 	__syscall_arg_t _arg4 = ARGIFY (arg4);				\ | |
| 236 | 	__syscall_arg_t _arg5 = ARGIFY (arg5);				\ | |
| 237 | 	register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\ | |
| 238 | 	 = (number);							\ | |
| 239 | 	register __syscall_arg_t __v0 asm ("$2");			\ | |
| 240 | 	register __syscall_arg_t __a0 asm ("$4") = _arg1;		\ | |
| 241 | 	register __syscall_arg_t __a1 asm ("$5") = _arg2;		\ | |
| 242 | 	register __syscall_arg_t __a2 asm ("$6") = _arg3;		\ | |
| 243 | 	register __syscall_arg_t __a3 asm ("$7") = _arg4;		\ | |
| 244 | 	register __syscall_arg_t __a4 asm ("$8") = _arg5;		\ | |
| 245 | 	__asm__ volatile (						\ | |
| 246 | 	".set\tnoreorder\n\t"						\ | |
| 247 | 	v0_init								\ | |
| 248 | 	"syscall\n\t"							\ | |
| 249 | 	".set\treorder"							\ | |
| 250 | 	: "=r" (__v0), "+r" (__a3)					\ | |
| 251 | 	: input, "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4)		\ | |
| 252 | 	: __SYSCALL_CLOBBERS);						\ | |
| 253 | 	_sys_result = __a3 != 0 ? -__v0 : __v0;				\ | |
| 254 | 	}								\ | |
| 255 | 	_sys_result;							\ | |
| 256 | }) | |
| 257 | ||
| 258 | #define internal_syscall6(v0_init, input, number, arg1, arg2, arg3, 	\ | |
| 259 | 			 arg4, arg5, arg6)				\ | |
| 260 | ({									\ | |
| 261 | 	long int _sys_result;						\ | |
| 262 | 									\ | |
| 263 | 	{								\ | |
| 264 | 	__syscall_arg_t _arg1 = ARGIFY (arg1);				\ | |
| 265 | 	__syscall_arg_t _arg2 = ARGIFY (arg2);				\ | |
| 266 | 	__syscall_arg_t _arg3 = ARGIFY (arg3);				\ | |
| 267 | 	__syscall_arg_t _arg4 = ARGIFY (arg4);				\ | |
| 268 | 	__syscall_arg_t _arg5 = ARGIFY (arg5);				\ | |
| 269 | 	__syscall_arg_t _arg6 = ARGIFY (arg6);				\ | |
| 270 | 	register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\ | |
| 271 | 	 = (number);							\ | |
| 272 | 	register __syscall_arg_t __v0 asm ("$2");			\ | |
| 273 | 	register __syscall_arg_t __a0 asm ("$4") = _arg1;		\ | |
| 274 | 	register __syscall_arg_t __a1 asm ("$5") = _arg2;		\ | |
| 275 | 	register __syscall_arg_t __a2 asm ("$6") = _arg3;		\ | |
| 276 | 	register __syscall_arg_t __a3 asm ("$7") = _arg4;		\ | |
| 277 | 	register __syscall_arg_t __a4 asm ("$8") = _arg5;		\ | |
| 278 | 	register __syscall_arg_t __a5 asm ("$9") = _arg6;		\ | |
| 279 | 	__asm__ volatile (						\ | |
| 280 | 	".set\tnoreorder\n\t"						\ | |
| 281 | 	v0_init								\ | |
| 282 | 	"syscall\n\t"							\ | |
| 283 | 	".set\treorder"							\ | |
| 284 | 	: "=r" (__v0), "+r" (__a3)					\ | |
| 285 | 	: input, "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4),	\ | |
| 286 | 	 "r" (__a5)							\ | |
| 287 | 	: __SYSCALL_CLOBBERS);						\ | |
| 288 | 	_sys_result = __a3 != 0 ? -__v0 : __v0;				\ | |
| 289 | 	}								\ | |
| 290 | 	_sys_result;							\ | |
| 291 | }) | |
| 292 | ||
| 293 | #if __mips_isa_rev >= 6 | |
| 294 | # define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", \ | |
| 295 | 	 "$14", "$15", "$24", "$25", "memory" | |
| 296 | #else | |
| 297 | # define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", \ | |
| 298 | 	 "$14", "$15", "$24", "$25", "hi", "lo", "memory" | |
| 299 | #endif | |
| 300 | ||
| 301 | #endif /* __ASSEMBLER__ */ | |
| 302 | ||
| 303 | /* Pointer mangling is not yet supported for MIPS. */ | |
| 304 | #define PTR_MANGLE(var) (void) (var) | |
| 305 | #define PTR_DEMANGLE(var) (void) (var) | |
| 306 | ||
| 307 | #endif /* linux/mips/sysdep.h */ |
lib/libc/glibc/sysdeps/unix/sysv/linux/mips/sysdep.h created+30| ... | ... | @@ -0,0 +1,30 @@ |
| 1 | /* Syscall definitions, Linux MIPS generic version. | |
| 2 | Copyright (C) 2019-2021 Free Software Foundation, Inc. | |
| 3 | This file is part of the GNU C Library. | |
| 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | |
| 6 | modify it under the terms of the GNU Lesser General Public | |
| 7 | License as published by the Free Software Foundation; either | |
| 8 | version 2.1 of the License, or (at your option) any later version. | |
| 9 | ||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 13 | Lesser General Public License for more details. | |
| 14 | ||
| 15 | You should have received a copy of the GNU Lesser General Public | |
| 16 | License along with the GNU C Library. If not, see | |
| 17 | <http://www.gnu.org/licenses/>. */ | |
| 18 | ||
| 19 | #include <sgidefs.h> | |
| 20 | ||
| 21 | #define VDSO_NAME "LINUX_2.6" | |
| 22 | #define VDSO_HASH 61765110 | |
| 23 | ||
| 24 | /* List of system calls which are supported as vsyscalls. */ | |
| 25 | #define HAVE_CLOCK_GETTIME_VSYSCALL "__vdso_clock_gettime" | |
| 26 | #if _MIPS_SIM != _ABI64 | |
| 27 | # define HAVE_CLOCK_GETTIME64_VSYSCALL "__vdso_clock_gettime64" | |
| 28 | #endif | |
| 29 | #define HAVE_GETTIMEOFDAY_VSYSCALL "__vdso_gettimeofday" | |
| 30 | #define HAVE_CLOCK_GETRES_VSYSCALL "__vdso_clock_getres" |
lib/libc/glibc/sysdeps/unix/sysv/linux/nios2/sysdep.h created+240| ... | ... | @@ -0,0 +1,240 @@ |
| 1 | /* Assembler macros for Nios II. | |
| 2 | Copyright (C) 2000-2021 Free Software Foundation, Inc. | |
| 3 | This file is part of the GNU C Library. | |
| 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | |
| 6 | modify it under the terms of the GNU Lesser General Public | |
| 7 | License as published by the Free Software Foundation; either | |
| 8 | version 2.1 of the License, or (at your option) any later version. | |
| 9 | ||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 13 | Lesser General Public License for more details. | |
| 14 | ||
| 15 | You should have received a copy of the GNU Lesser General Public | |
| 16 | License along with the GNU C Library; if not, see | |
| 17 | <https://www.gnu.org/licenses/>. */ | |
| 18 | ||
| 19 | #ifndef _LINUX_NIOS2_SYSDEP_H | |
| 20 | #define _LINUX_NIOS2_SYSDEP_H 1 | |
| 21 | ||
| 22 | #include <sysdeps/unix/sysdep.h> | |
| 23 | #include <sysdeps/nios2/sysdep.h> | |
| 24 | #include <sysdeps/unix/sysv/linux/generic/sysdep.h> | |
| 25 | ||
| 26 | /* For RTLD_PRIVATE_ERRNO. */ | |
| 27 | #include <dl-sysdep.h> | |
| 28 | ||
| 29 | #include <tls.h> | |
| 30 | ||
| 31 | /* For Linux we can use the system call table in the header file | |
| 32 | /usr/include/asm/unistd.h | |
| 33 | of the kernel. But these symbols do not follow the SYS_* syntax | |
| 34 | so we have to redefine the `SYS_ify' macro here. */ | |
| 35 | #undef SYS_ify | |
| 36 | #define SYS_ify(syscall_name) __NR_##syscall_name | |
| 37 | ||
| 38 | #ifdef __ASSEMBLER__ | |
| 39 | ||
| 40 | #undef SYSCALL_ERROR_LABEL | |
| 41 | #define SYSCALL_ERROR_LABEL __local_syscall_error | |
| 42 | ||
| 43 | #undef PSEUDO | |
| 44 | #define PSEUDO(name, syscall_name, args) \ | |
| 45 | ENTRY (name) \ | |
| 46 | DO_CALL (syscall_name, args) \ | |
| 47 | bne r7, zero, SYSCALL_ERROR_LABEL; \ | |
| 48 | ||
| 49 | #undef PSEUDO_END | |
| 50 | #define PSEUDO_END(name) \ | |
| 51 | SYSCALL_ERROR_HANDLER \ | |
| 52 | END (name) | |
| 53 | ||
| 54 | #undef PSEUDO_NOERRNO | |
| 55 | #define PSEUDO_NOERRNO(name, syscall_name, args) \ | |
| 56 | ENTRY (name) \ | |
| 57 | DO_CALL (syscall_name, args) | |
| 58 | ||
| 59 | #undef PSEUDO_END_NOERRNO | |
| 60 | #define PSEUDO_END_NOERRNO(name) \ | |
| 61 | END (name) | |
| 62 | ||
| 63 | #undef ret_NOERRNO | |
| 64 | #define ret_NOERRNO ret | |
| 65 | ||
| 66 | #undef DO_CALL | |
| 67 | #define DO_CALL(syscall_name, args) \ | |
| 68 | DOARGS_##args \ | |
| 69 | movi r2, SYS_ify(syscall_name); \ | |
| 70 | trap; | |
| 71 | ||
| 72 | #if defined(__PIC__) || defined(PIC) | |
| 73 | ||
| 74 | # if RTLD_PRIVATE_ERRNO | |
| 75 | ||
| 76 | # define SYSCALL_ERROR_HANDLER			\ | |
| 77 | SYSCALL_ERROR_LABEL:				\ | |
| 78 | nextpc r3;					\ | |
| 79 | 1:						\ | |
| 80 | movhi r8, %hiadj(rtld_errno - 1b);		\ | |
| 81 | addi r8, r8, %lo(rtld_errno - 1b);		\ | |
| 82 | add r3, r3, r8;				\ | |
| 83 | stw r2, 0(r3);				\ | |
| 84 | movi r2, -1;					\ | |
| 85 | ret; | |
| 86 | ||
| 87 | # else | |
| 88 | ||
| 89 | # if IS_IN (libc) | |
| 90 | # define SYSCALL_ERROR_ERRNO __libc_errno | |
| 91 | # else | |
| 92 | # define SYSCALL_ERROR_ERRNO errno | |
| 93 | # endif | |
| 94 | # define SYSCALL_ERROR_HANDLER			\ | |
| 95 | SYSCALL_ERROR_LABEL:				\ | |
| 96 | nextpc r3;					\ | |
| 97 | 1:						\ | |
| 98 | movhi r8, %hiadj(_gp_got - 1b);		\ | |
| 99 | addi r8, r8, %lo(_gp_got - 1b);		\ | |
| 100 | add r3, r3, r8;				\ | |
| 101 | ldw r3, %tls_ie(SYSCALL_ERROR_ERRNO)(r3);	\ | |
| 102 | add r3, r23, r3;				\ | |
| 103 | stw r2, 0(r3);				\ | |
| 104 | movi r2, -1;					\ | |
| 105 | ret; | |
| 106 | ||
| 107 | # endif | |
| 108 | ||
| 109 | #else | |
| 110 | ||
| 111 | /* We can use a single error handler in the static library. */ | |
| 112 | #define SYSCALL_ERROR_HANDLER			\ | |
| 113 | SYSCALL_ERROR_LABEL:				\ | |
| 114 | jmpi __syscall_error; | |
| 115 | ||
| 116 | #endif | |
| 117 | ||
| 118 | #define DOARGS_0 /* nothing */ | |
| 119 | #define DOARGS_1 /* nothing */ | |
| 120 | #define DOARGS_2 /* nothing */ | |
| 121 | #define DOARGS_3 /* nothing */ | |
| 122 | #define DOARGS_4 /* nothing */ | |
| 123 | #define DOARGS_5 ldw r8, 0(sp); | |
| 124 | #define DOARGS_6 ldw r9, 4(sp); ldw r8, 0(sp); | |
| 125 | ||
| 126 | /* The function has to return the error code. */ | |
| 127 | #undef PSEUDO_ERRVAL | |
| 128 | #define PSEUDO_ERRVAL(name, syscall_name, args) \ | |
| 129 | ENTRY (name) \ | |
| 130 | DO_CALL (syscall_name, args) | |
| 131 | ||
| 132 | #undef PSEUDO_END_ERRVAL | |
| 133 | #define PSEUDO_END_ERRVAL(name) \ | |
| 134 | END (name) | |
| 135 | ||
| 136 | #define ret_ERRVAL ret | |
| 137 | ||
| 138 | #else /* __ASSEMBLER__ */ | |
| 139 | ||
| 140 | /* In order to get __set_errno() definition in INLINE_SYSCALL. */ | |
| 141 | #include <errno.h> | |
| 142 | ||
| 143 | #undef INTERNAL_SYSCALL_RAW | |
| 144 | #define INTERNAL_SYSCALL_RAW(name, nr, args...) \ | |
| 145 | ({ unsigned int _sys_result; \ | |
| 146 | { \ | |
| 147 | /* Load argument values in temporary variables | |
| 148 | 	 to perform side effects like function calls | |
| 149 | 	 before the call-used registers are set. */		\ | |
| 150 | LOAD_ARGS_##nr (args)					\ | |
| 151 | LOAD_REGS_##nr						\ | |
| 152 | register int _r2 asm ("r2") = (int)(name); \ | |
| 153 | register int _err asm ("r7"); \ | |
| 154 | asm volatile ("trap" \ | |
| 155 | : "+r" (_r2), "=r" (_err) \ | |
| 156 | : ASM_ARGS_##nr				\ | |
| 157 | : __SYSCALL_CLOBBERS); \ | |
| 158 | _sys_result = _err != 0 ? -_r2 : _r2; \ | |
| 159 | } \ | |
| 160 | (int) _sys_result; }) | |
| 161 | ||
| 162 | #undef INTERNAL_SYSCALL | |
| 163 | #define INTERNAL_SYSCALL(name, nr, args...) \ | |
| 164 | 	INTERNAL_SYSCALL_RAW(SYS_ify(name), nr, args) | |
| 165 | ||
| 166 | #undef INTERNAL_SYSCALL_NCS | |
| 167 | #define INTERNAL_SYSCALL_NCS(number, nr, args...) \ | |
| 168 | 	INTERNAL_SYSCALL_RAW(number, nr, args) | |
| 169 | ||
| 170 | #define LOAD_ARGS_0() | |
| 171 | #define LOAD_REGS_0 | |
| 172 | #define ASM_ARGS_0 | |
| 173 | #define LOAD_ARGS_1(a1)				\ | |
| 174 | LOAD_ARGS_0 ()				\ | |
| 175 | int __arg1 = (int) (a1); | |
| 176 | #define LOAD_REGS_1				\ | |
| 177 | register int _r4 asm ("r4") = __arg1;		\ | |
| 178 | LOAD_REGS_0 | |
| 179 | #define ASM_ARGS_1 "r" (_r4) | |
| 180 | #define LOAD_ARGS_2(a1, a2)			\ | |
| 181 | LOAD_ARGS_1 (a1)				\ | |
| 182 | int __arg2 = (int) (a2); | |
| 183 | #define LOAD_REGS_2				\ | |
| 184 | register int _r5 asm ("r5") = __arg2;		\ | |
| 185 | LOAD_REGS_1 | |
| 186 | #define ASM_ARGS_2 ASM_ARGS_1, "r" (_r5) | |
| 187 | #define LOAD_ARGS_3(a1, a2, a3)			\ | |
| 188 | LOAD_ARGS_2 (a1, a2)				\ | |
| 189 | int __arg3 = (int) (a3); | |
| 190 | #define LOAD_REGS_3				\ | |
| 191 | register int _r6 asm ("r6") = __arg3;		\ | |
| 192 | LOAD_REGS_2 | |
| 193 | #define ASM_ARGS_3 ASM_ARGS_2, "r" (_r6) | |
| 194 | #define LOAD_ARGS_4(a1, a2, a3, a4)		\ | |
| 195 | LOAD_ARGS_3 (a1, a2, a3)			\ | |
| 196 | int __arg4 = (int) (a4); | |
| 197 | #define LOAD_REGS_4				\ | |
| 198 | register int _r7 asm ("r7") = __arg4;		\ | |
| 199 | LOAD_REGS_3 | |
| 200 | #define ASM_ARGS_4 ASM_ARGS_3, "r" (_r7) | |
| 201 | #define LOAD_ARGS_5(a1, a2, a3, a4, a5)		\ | |
| 202 | LOAD_ARGS_4 (a1, a2, a3, a4)			\ | |
| 203 | int __arg5 = (int) (a5); | |
| 204 | #define LOAD_REGS_5				\ | |
| 205 | register int _r8 asm ("r8") = __arg5;		\ | |
| 206 | LOAD_REGS_4 | |
| 207 | #define ASM_ARGS_5 ASM_ARGS_4, "r" (_r8) | |
| 208 | #define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6)	\ | |
| 209 | LOAD_ARGS_5 (a1, a2, a3, a4, a5)		\ | |
| 210 | int __arg6 = (int) (a6); | |
| 211 | #define LOAD_REGS_6			 \ | |
| 212 | register int _r9 asm ("r9") = __arg6; \ | |
| 213 | LOAD_REGS_5 | |
| 214 | #define ASM_ARGS_6 ASM_ARGS_5, "r" (_r9) | |
| 215 | ||
| 216 | #define __SYSCALL_CLOBBERS "memory" | |
| 217 | ||
| 218 | #undef HAVE_INTERNAL_BRK_ADDR_SYMBOL | |
| 219 | #define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1 | |
| 220 | ||
| 221 | #endif /* __ASSEMBLER__ */ | |
| 222 | ||
| 223 | /* Pointer mangling support. */ | |
| 224 | #if IS_IN (rtld) | |
| 225 | /* We cannot use the thread descriptor because in ld.so we use setjmp | |
| 226 | earlier than the descriptor is initialized. */ | |
| 227 | #else | |
| 228 | # ifdef __ASSEMBLER__ | |
| 229 | # define PTR_MANGLE_GUARD(guard) ldw guard, POINTER_GUARD(r23) | |
| 230 | # define PTR_MANGLE(dst, src, guard) xor dst, src, guard | |
| 231 | # define PTR_DEMANGLE(dst, src, guard) PTR_MANGLE (dst, src, guard) | |
| 232 | # else | |
| 233 | # define PTR_MANGLE(var) \ | |
| 234 | (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ()) | |
| 235 | # define PTR_DEMANGLE(var)	PTR_MANGLE (var) | |
| 236 | # endif | |
| 237 | #endif | |
| 238 | ||
| 239 | ||
| 240 | #endif /* linux/nios2/sysdep.h */ |
lib/libc/glibc/sysdeps/unix/sysv/linux/powerpc/sysdep.h created+265| ... | ... | @@ -0,0 +1,265 @@ |
| 1 | /* Syscall definitions, Linux PowerPC generic version. | |
| 2 | Copyright (C) 2019-2021 Free Software Foundation, Inc. | |
| 3 | This file is part of the GNU C Library. | |
| 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | |
| 6 | modify it under the terms of the GNU Lesser General Public | |
| 7 | License as published by the Free Software Foundation; either | |
| 8 | version 2.1 of the License, or (at your option) any later version. | |
| 9 | ||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 13 | Lesser General Public License for more details. | |
| 14 | ||
| 15 | You should have received a copy of the GNU Lesser General Public | |
| 16 | License along with the GNU C Library; if not, see | |
| 17 | <http://www.gnu.org/licenses/>. */ | |
| 18 | ||
| 19 | #ifndef _LINUX_POWERPC_SYSDEP_H | |
| 20 | #define _LINUX_POWERPC_SYSDEP_H 1 | |
| 21 | ||
| 22 | #include <sysdeps/unix/sysv/linux/sysdep.h> | |
| 23 | #include <sysdeps/unix/powerpc/sysdep.h> | |
| 24 | #include <tls.h> | |
| 25 | /* Define __set_errno() for INLINE_SYSCALL macro below. */ | |
| 26 | #include <errno.h> | |
| 27 | ||
| 28 | /* For Linux we can use the system call table in the header file | |
| 29 | /usr/include/asm/unistd.h | |
| 30 | of the kernel. But these symbols do not follow the SYS_* syntax | |
| 31 | so we have to redefine the `SYS_ify' macro here. */ | |
| 32 | #undef SYS_ify | |
| 33 | #define SYS_ify(syscall_name) __NR_##syscall_name | |
| 34 | ||
| 35 | /* Define a macro which expands inline into the wrapper code for a system | |
| 36 | call. This use is for internal calls that do not need to handle errors | |
| 37 | normally. It will never touch errno. This returns just what the kernel | |
| 38 | gave back in the non-error (CR0.SO cleared) case, otherwise (CR0.SO set) | |
| 39 | the negation of the return value in the kernel gets reverted. */ | |
| 40 | ||
| 41 | #define INTERNAL_VSYSCALL_CALL_TYPE(funcptr, type, nr, args...) \ | |
| 42 | ({									\ | |
| 43 | register void *r0 __asm__ ("r0");					\ | |
| 44 | register long int r3 __asm__ ("r3");				\ | |
| 45 | register long int r4 __asm__ ("r4");				\ | |
| 46 | register long int r5 __asm__ ("r5");				\ | |
| 47 | register long int r6 __asm__ ("r6");				\ | |
| 48 | register long int r7 __asm__ ("r7");				\ | |
| 49 | register long int r8 __asm__ ("r8");				\ | |
| 50 | register type rval __asm__ ("r3");				 \ | |
| 51 | LOADARGS_##nr (funcptr, args);					\ | |
| 52 | __asm__ __volatile__						\ | |
| 53 | ("mtctr %0\n\t"							\ | |
| 54 | "bctrl\n\t"							\ | |
| 55 | "mfcr %0\n\t"							\ | |
| 56 | "0:"								\ | |
| 57 | : "+r" (r0), "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), \ | |
| 58 | "+r" (r7), "+r" (r8)						\ | |
| 59 | : : "r9", "r10", "r11", "r12",					\ | |
| 60 | "cr0", "cr1", "cr5", "cr6", "cr7",				\ | |
| 61 | "xer", "lr", "ctr", "memory");				\ | |
| 62 | __asm__ __volatile__ ("" : "=r" (rval) : "r" (r3));		 \ | |
| 63 | (long int) r0 & (1 << 28) ? -rval : rval;				\ | |
| 64 | }) | |
| 65 | ||
| 66 | #define INTERNAL_VSYSCALL_CALL(funcptr, nr, args...)			\ | |
| 67 | INTERNAL_VSYSCALL_CALL_TYPE(funcptr, long int, nr, args) | |
| 68 | ||
| 69 | #define DECLARE_REGS				\ | |
| 70 | register long int r0 __asm__ ("r0");		\ | |
| 71 | register long int r3 __asm__ ("r3");		\ | |
| 72 | register long int r4 __asm__ ("r4");		\ | |
| 73 | register long int r5 __asm__ ("r5");		\ | |
| 74 | register long int r6 __asm__ ("r6");		\ | |
| 75 | register long int r7 __asm__ ("r7");		\ | |
| 76 | register long int r8 __asm__ ("r8"); | |
| 77 | ||
| 78 | #define SYSCALL_SCV(nr)				\ | |
| 79 | ({						\ | |
| 80 | __asm__ __volatile__			\ | |
| 81 | (".machine \"push\"\n\t"			\ | |
| 82 | ".machine \"power9\"\n\t"		\ | |
| 83 | "scv 0\n\t"				\ | |
| 84 | ".machine \"pop\"\n\t"			\ | |
| 85 | "0:"					\ | |
| 86 | : "=&r" (r0),				\ | |
| 87 | 	 "=&r" (r3), "=&r" (r4), "=&r" (r5),	\ | |
| 88 | 	 "=&r" (r6), "=&r" (r7), "=&r" (r8)	\ | |
| 89 | : ASM_INPUT_##nr			\ | |
| 90 | : "r9", "r10", "r11", "r12",		\ | |
| 91 | 	 "cr0", "cr1", "cr5", "cr6", "cr7",	\ | |
| 92 | 	 "xer", "lr", "ctr", "memory"); 	\ | |
| 93 | r3;					\ | |
| 94 | }) | |
| 95 | ||
| 96 | #define SYSCALL_SC(nr)				\ | |
| 97 | ({						\ | |
| 98 | __asm__ __volatile__			\ | |
| 99 | ("sc\n\t"				\ | |
| 100 | "mfcr %0\n\t"				\ | |
| 101 | "0:"					\ | |
| 102 | : "=&r" (r0),				\ | |
| 103 | 	 "=&r" (r3), "=&r" (r4), "=&r" (r5),	\ | |
| 104 | 	 "=&r" (r6), "=&r" (r7), "=&r" (r8)	\ | |
| 105 | : ASM_INPUT_##nr			\ | |
| 106 | : "r9", "r10", "r11", "r12",		\ | |
| 107 | 	 "xer", "cr0", "ctr", "memory");	\ | |
| 108 | r0 & (1 << 28) ? -r3 : r3;			\ | |
| 109 | }) | |
| 110 | ||
| 111 | /* This will only be non-empty for 64-bit systems, see below. */ | |
| 112 | #define TRY_SYSCALL_SCV(nr) | |
| 113 | ||
| 114 | #if defined(__PPC64__) || defined(__powerpc64__) | |
| 115 | # define SYSCALL_ARG_SIZE 8 | |
| 116 | ||
| 117 | /* For the static case, unlike the dynamic loader, there is no compile-time way | |
| 118 | to check if we are inside startup code. So we need to check if the thread | |
| 119 | pointer has already been setup before trying to access the TLS. */ | |
| 120 | # ifndef SHARED | |
| 121 | # define CHECK_THREAD_POINTER (__thread_register != 0) | |
| 122 | # else | |
| 123 | # define CHECK_THREAD_POINTER (1) | |
| 124 | # endif | |
| 125 | ||
| 126 | /* When inside the dynamic loader, the thread pointer may not have been | |
| 127 | initialized yet, so don't check for scv support in that case. */ | |
| 128 | # if defined(USE_PPC_SCV) && !IS_IN(rtld) | |
| 129 | # undef TRY_SYSCALL_SCV | |
| 130 | # define TRY_SYSCALL_SCV(nr)						\ | |
| 131 | CHECK_THREAD_POINTER && THREAD_GET_HWCAP() & PPC_FEATURE2_SCV ?	\ | |
| 132 | SYSCALL_SCV(nr) : | |
| 133 | # endif | |
| 134 | ||
| 135 | #else | |
| 136 | # define SYSCALL_ARG_SIZE 4 | |
| 137 | #endif | |
| 138 | ||
| 139 | # define INTERNAL_SYSCALL_NCS(name, nr, args...)	\ | |
| 140 | ({							\ | |
| 141 | DECLARE_REGS;					\ | |
| 142 | LOADARGS_##nr (name, ##args);			\ | |
| 143 | TRY_SYSCALL_SCV(nr)					\ | |
| 144 | SYSCALL_SC(nr);					\ | |
| 145 | }) | |
| 146 | ||
| 147 | #undef INTERNAL_SYSCALL | |
| 148 | #define INTERNAL_SYSCALL(name, nr, args...)				\ | |
| 149 | INTERNAL_SYSCALL_NCS (__NR_##name, nr, args) | |
| 150 | ||
| 151 | #define LOADARGS_0(name, dummy) \ | |
| 152 | 	r0 = name | |
| 153 | #define LOADARGS_1(name, __arg1) \ | |
| 154 | 	long int _arg1 = (long int) (__arg1); \ | |
| 155 | 	LOADARGS_0(name, 0); \ | |
| 156 | 	extern void __illegally_sized_syscall_arg1 (void); \ | |
| 157 | 	if (__builtin_classify_type (__arg1) != 5 \ | |
| 158 | 	 && sizeof (__arg1) > SYSCALL_ARG_SIZE) \ | |
| 159 | 	 __illegally_sized_syscall_arg1 (); \ | |
| 160 | 	r3 = _arg1 | |
| 161 | #define LOADARGS_2(name, __arg1, __arg2) \ | |
| 162 | 	long int _arg2 = (long int) (__arg2); \ | |
| 163 | 	LOADARGS_1(name, __arg1); \ | |
| 164 | 	extern void __illegally_sized_syscall_arg2 (void); \ | |
| 165 | 	if (__builtin_classify_type (__arg2) != 5 \ | |
| 166 | 	 && sizeof (__arg2) > SYSCALL_ARG_SIZE) \ | |
| 167 | 	 __illegally_sized_syscall_arg2 (); \ | |
| 168 | 	r4 = _arg2 | |
| 169 | #define LOADARGS_3(name, __arg1, __arg2, __arg3) \ | |
| 170 | 	long int _arg3 = (long int) (__arg3); \ | |
| 171 | 	LOADARGS_2(name, __arg1, __arg2); \ | |
| 172 | 	extern void __illegally_sized_syscall_arg3 (void); \ | |
| 173 | 	if (__builtin_classify_type (__arg3) != 5 \ | |
| 174 | 	 && sizeof (__arg3) > SYSCALL_ARG_SIZE) \ | |
| 175 | 	 __illegally_sized_syscall_arg3 (); \ | |
| 176 | 	r5 = _arg3 | |
| 177 | #define LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4) \ | |
| 178 | 	long int _arg4 = (long int) (__arg4); \ | |
| 179 | 	LOADARGS_3(name, __arg1, __arg2, __arg3); \ | |
| 180 | 	extern void __illegally_sized_syscall_arg4 (void); \ | |
| 181 | 	if (__builtin_classify_type (__arg4) != 5 \ | |
| 182 | 	 && sizeof (__arg4) > SYSCALL_ARG_SIZE) \ | |
| 183 | 	 __illegally_sized_syscall_arg4 (); \ | |
| 184 | 	r6 = _arg4 | |
| 185 | #define LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5) \ | |
| 186 | 	long int _arg5 = (long int) (__arg5); \ | |
| 187 | 	LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4); \ | |
| 188 | 	extern void __illegally_sized_syscall_arg5 (void); \ | |
| 189 | 	if (__builtin_classify_type (__arg5) != 5 \ | |
| 190 | 	 && sizeof (__arg5) > SYSCALL_ARG_SIZE) \ | |
| 191 | 	 __illegally_sized_syscall_arg5 (); \ | |
| 192 | 	r7 = _arg5 | |
| 193 | #define LOADARGS_6(name, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) \ | |
| 194 | 	long int _arg6 = (long int) (__arg6); \ | |
| 195 | 	LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5); \ | |
| 196 | 	extern void __illegally_sized_syscall_arg6 (void); \ | |
| 197 | 	if (__builtin_classify_type (__arg6) != 5 \ | |
| 198 | 	 && sizeof (__arg6) > SYSCALL_ARG_SIZE) \ | |
| 199 | 	 __illegally_sized_syscall_arg6 (); \ | |
| 200 | 	r8 = _arg6 | |
| 201 | ||
| 202 | #define ASM_INPUT_0 "0" (r0) | |
| 203 | #define ASM_INPUT_1 ASM_INPUT_0, "1" (r3) | |
| 204 | #define ASM_INPUT_2 ASM_INPUT_1, "2" (r4) | |
| 205 | #define ASM_INPUT_3 ASM_INPUT_2, "3" (r5) | |
| 206 | #define ASM_INPUT_4 ASM_INPUT_3, "4" (r6) | |
| 207 | #define ASM_INPUT_5 ASM_INPUT_4, "5" (r7) | |
| 208 | #define ASM_INPUT_6 ASM_INPUT_5, "6" (r8) | |
| 209 | ||
| 210 | ||
| 211 | /* Pointer mangling support. */ | |
| 212 | #if IS_IN (rtld) | |
| 213 | /* We cannot use the thread descriptor because in ld.so we use setjmp | |
| 214 | earlier than the descriptor is initialized. */ | |
| 215 | #else | |
| 216 | # ifdef __ASSEMBLER__ | |
| 217 | # if defined(__PPC64__) || defined(__powerpc64__) | |
| 218 | # define LOAD ld | |
| 219 | # define TPREG r13 | |
| 220 | # else | |
| 221 | # define LOAD lwz | |
| 222 | # define TPREG r2 | |
| 223 | # endif | |
| 224 | # define PTR_MANGLE(reg, tmpreg) \ | |
| 225 | 	LOAD	tmpreg,POINTER_GUARD(TPREG); \ | |
| 226 | 	xor	reg,tmpreg,reg | |
| 227 | # define PTR_MANGLE2(reg, tmpreg) \ | |
| 228 | 	xor	reg,tmpreg,reg | |
| 229 | # define PTR_MANGLE3(destreg, reg, tmpreg) \ | |
| 230 | 	LOAD	tmpreg,POINTER_GUARD(TPREG); \ | |
| 231 | 	xor	destreg,tmpreg,reg | |
| 232 | # define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg) | |
| 233 | # define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg) | |
| 234 | # define PTR_DEMANGLE3(destreg, reg, tmpreg) PTR_MANGLE3 (destreg, reg, tmpreg) | |
| 235 | # else | |
| 236 | # define PTR_MANGLE(var) \ | |
| 237 | (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ()) | |
| 238 | # define PTR_DEMANGLE(var)	PTR_MANGLE (var) | |
| 239 | # endif | |
| 240 | #endif | |
| 241 | ||
| 242 | /* List of system calls which are supported as vsyscalls. */ | |
| 243 | #define VDSO_NAME "LINUX_2.6.15" | |
| 244 | #define VDSO_HASH 123718565 | |
| 245 | ||
| 246 | #if defined(__PPC64__) || defined(__powerpc64__) | |
| 247 | #define HAVE_CLOCK_GETRES64_VSYSCALL	"__kernel_clock_getres" | |
| 248 | #define HAVE_CLOCK_GETTIME64_VSYSCALL	"__kernel_clock_gettime" | |
| 249 | #else | |
| 250 | #define HAVE_CLOCK_GETRES_VSYSCALL	"__kernel_clock_getres" | |
| 251 | #define HAVE_CLOCK_GETTIME_VSYSCALL	"__kernel_clock_gettime" | |
| 252 | #endif | |
| 253 | #define HAVE_GETCPU_VSYSCALL		"__kernel_getcpu" | |
| 254 | #define HAVE_TIME_VSYSCALL		"__kernel_time" | |
| 255 | #define HAVE_GETTIMEOFDAY_VSYSCALL "__kernel_gettimeofday" | |
| 256 | #define HAVE_GET_TBFREQ "__kernel_get_tbfreq" | |
| 257 | ||
| 258 | #if defined(__PPC64__) || defined(__powerpc64__) | |
| 259 | # define HAVE_SIGTRAMP_RT64		"__kernel_sigtramp_rt64" | |
| 260 | #else | |
| 261 | # define HAVE_SIGTRAMP_32		"__kernel_sigtramp32" | |
| 262 | # define HAVE_SIGTRAMP_RT32		"__kernel_sigtramp_rt32" | |
| 263 | #endif | |
| 264 | ||
| 265 | #endif /* _LINUX_POWERPC_SYSDEP_H */ |
lib/libc/glibc/sysdeps/unix/sysv/linux/s390/sysdep.h created+113| ... | ... | @@ -0,0 +1,113 @@ |
| 1 | /* Syscall definitions, Linux s390 version. | |
| 2 | Copyright (C) 2019-2021 Free Software Foundation, Inc. | |
| 3 | This file is part of the GNU C Library. | |
| 4 | ||
| 5 | The GNU C Library is free software; you can redistribute it and/or | |
| 6 | modify it under the terms of the GNU Lesser General Public | |
| 7 | License as published by the Free Software Foundation; either | |
| 8 | version 2.1 of the License, or (at your option) any later version. | |
| 9 | ||
| 10 | The GNU C Library is distributed in the hope that it will be useful, | |
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 13 | Lesser General Public License for more details. | |
| 14 | ||
| 15 | You should have received a copy of the GNU Lesser General Public | |
| 16 | License along with the GNU C Library; if not, see | |
| 17 | <http://www.gnu.org/licenses/>. */ | |
| 18 | ||
| 19 | #ifndef __ASSEMBLY__ | |
| 20 | ||
| 21 | #undef SYS_ify | |
| 22 | #define SYS_ify(syscall_name)	__NR_##syscall_name | |
| 23 | ||
| 24 | #undef INTERNAL_SYSCALL_DIRECT | |
| 25 | #define INTERNAL_SYSCALL_DIRECT(name, nr, args...)			 \ | |
| 26 | ({									 \ | |
| 27 | DECLARGS_##nr(args)							 \ | |
| 28 | register long int _ret __asm__("2");				 \ | |
| 29 | __asm__ __volatile__ (						 \ | |
| 30 | 			 "svc %b1\n\t"				 \ | |
| 31 | 			 : "=d" (_ret)					 \ | |
| 32 | 			 : "i" (__NR_##name) ASMFMT_##nr		 \ | |
| 33 | 			 : "memory" );					 \ | |
| 34 | _ret; }) | |
| 35 | ||
| 36 | #undef INTERNAL_SYSCALL_SVC0 | |
| 37 | #define INTERNAL_SYSCALL_SVC0(name, nr, args...)			 \ | |
| 38 | ({									 \ | |
| 39 | DECLARGS_##nr(args)							 \ | |
| 40 | register unsigned long int _nr __asm__("1") =			 \ | |
| 41 | (unsigned long int)(__NR_##name);					 \ | |
| 42 | register long int _ret __asm__("2");				 \ | |
| 43 | __asm__ __volatile__ (						 \ | |
| 44 | 			 "svc 0\n\t"				 \ | |
| 45 | 			 : "=d" (_ret)					 \ | |
| 46 | 			 : "d" (_nr) ASMFMT_##nr			 \ | |
| 47 | 			 : "memory" );					 \ | |
| 48 | _ret; }) | |
| 49 | ||
| 50 | #undef INTERNAL_SYSCALL_NCS | |
| 51 | #define INTERNAL_SYSCALL_NCS(no, nr, args...)				 \ | |
| 52 | ({									 \ | |
| 53 | DECLARGS_##nr(args)							 \ | |
| 54 | register unsigned long int _nr __asm__("1") = (unsigned long int)(no); \ | |
| 55 | register long int _ret __asm__("2");				 \ | |
| 56 | __asm__ __volatile__ (						 \ | |
| 57 | 			 "svc 0\n\t"				 \ | |
| 58 | 			 : "=d" (_ret)					 \ | |
| 59 | 			 : "d" (_nr) ASMFMT_##nr			 \ | |
| 60 | 			 : "memory" );					 \ | |
| 61 | _ret; }) | |
| 62 | ||
| 63 | #undef INTERNAL_SYSCALL | |
| 64 | #define INTERNAL_SYSCALL(name, nr, args...)				 \ | |
| 65 | (((__NR_##name) < 256)						 \ | |
| 66 | ? INTERNAL_SYSCALL_DIRECT(name, nr, args)				 \ | |
| 67 | : INTERNAL_SYSCALL_SVC0(name, nr, args)) | |
| 68 | ||
| 69 | #define DECLARGS_0() | |
| 70 | #define DECLARGS_1(arg1) \ | |
| 71 | register unsigned long int gpr2 __asm__ ("2") = (unsigned long int)(arg1); | |
| 72 | #define DECLARGS_2(arg1, arg2) \ | |
| 73 | DECLARGS_1(arg1) \ | |
| 74 | register unsigned long int gpr3 __asm__ ("3") = (unsigned long int)(arg2); | |
| 75 | #define DECLARGS_3(arg1, arg2, arg3) \ | |
| 76 | DECLARGS_2(arg1, arg2) \ | |
| 77 | register unsigned long int gpr4 __asm__ ("4") = (unsigned long int)(arg3); | |
| 78 | #define DECLARGS_4(arg1, arg2, arg3, arg4) \ | |
| 79 | DECLARGS_3(arg1, arg2, arg3) \ | |
| 80 | register unsigned long int gpr5 __asm__ ("5") = (unsigned long int)(arg4); | |
| 81 | #define DECLARGS_5(arg1, arg2, arg3, arg4, arg5) \ | |
| 82 | DECLARGS_4(arg1, arg2, arg3, arg4) \ | |
| 83 | register unsigned long int gpr6 __asm__ ("6") = (unsigned long int)(arg5); | |
| 84 | #define DECLARGS_6(arg1, arg2, arg3, arg4, arg5, arg6) \ | |
| 85 | DECLARGS_5(arg1, arg2, arg3, arg4, arg5) \ | |
| 86 | register unsigned long int gpr7 __asm__ ("7") = (unsigned long int)(arg6); | |
| 87 | ||
| 88 | #define ASMFMT_0 | |
| 89 | #define ASMFMT_1 , "0" (gpr2) | |
| 90 | #define ASMFMT_2 , "0" (gpr2), "d" (gpr3) | |
| 91 | #define ASMFMT_3 , "0" (gpr2), "d" (gpr3), "d" (gpr4) | |
| 92 | #define ASMFMT_4 , "0" (gpr2), "d" (gpr3), "d" (gpr4), "d" (gpr5) | |
| 93 | #define ASMFMT_5 , "0" (gpr2), "d" (gpr3), "d" (gpr4), "d" (gpr5), "d" (gpr6) | |
| 94 | #define ASMFMT_6 , "0" (gpr2), "d" (gpr3), "d" (gpr4), "d" (gpr5), "d" (gpr6), "d" (gpr7) | |
| 95 | ||
| 96 | #define SINGLE_THREAD_BY_GLOBAL		1 | |
| 97 | ||
| 98 | ||
| 99 | #define VDSO_NAME "LINUX_2.6.29" | |
| 100 | #define VDSO_HASH 123718585 | |
| 101 | ||
| 102 | /* List of system calls which are supported as vsyscalls. */ | |
| 103 | #ifdef __s390x__ | |
| 104 | #define HAVE_CLOCK_GETRES64_VSYSCALL	"__kernel_clock_getres" | |
| 105 | #define HAVE_CLOCK_GETTIME64_VSYSCALL	"__kernel_clock_gettime" | |
| 106 | #else | |
| 107 | #define HAVE_CLOCK_GETRES_VSYSCALL	"__kernel_clock_getres" | |
| 108 | #define HAVE_CLOCK_GETTIME_VSYSCALL	"__kernel_clock_gettime" | |
| 109 | #endif | |
| 110 | #define HAVE_GETTIMEOFDAY_VSYSCALL	"__kernel_gettimeofday" | |
| 111 | #define HAVE_GETCPU_VSYSCALL		"__kernel_getcpu" | |
| 112 | ||
| 113 | #endif |