You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
540 lines
17 KiB
540 lines
17 KiB
7 years ago
|
From 9a7cb556eef7cb75b31d0bc05f73c6338dfd8e49 Mon Sep 17 00:00:00 2001
|
||
|
From: Richard Henderson <rth@redhat.com>
|
||
|
Date: Fri, 30 May 2014 13:57:04 -0400
|
||
|
Subject: [PATCH] aarch64: Backport syscall rewrite
|
||
|
|
||
|
From commits:
|
||
|
a60339aaff82beadea6f580e587d64052cb5e3b8 Fix handling of nocancel syscall...
|
||
|
3612eb8f25d978e7e4ac536a34098091f737161c Merge rtld_errno offset w/ mem ref
|
||
|
a6b3657be6bc5067aeec98d990f60765361c6557 Merge __local_multiple_threads ofs...
|
||
|
c69abcee726a6f63d9e5e8f0d9dcc79374ee3ef8 Fix DO_CALL block comment
|
||
|
6e6c2d01ebb1ef839675c7151d2a114f53663386 Remove DOARGS/UNDOARGS macros
|
||
|
ca3cfa40c16ef34c74951a07a57cfcbcd58898b1 Tidy syscall error check
|
||
|
af4e8ef9443e258ebeb0ddf3c5c9579f24dfacd5 Tabify sysdep-cancel.h
|
||
|
a8b4f04ad7dff4f39797a7ab7f8babda54266026 Share code in sysdep-cancel.h
|
||
|
645d44abe3ca6253a9d4762f092e4a1b9d294b11 Pass regno parameter to SINGLE_THREAD_P
|
||
|
b5be4597716eff94149f5529c8eb2cd3b4296188 Improve syscall-cancel stack frame
|
||
|
74f31c18593111725478a991b395ae45661985a3 Fix error return from __ioctl
|
||
|
f0712b543eaddeca8fc6d7a8eb6b5b8d24105ce2 Remove PSEUDO_RET
|
||
|
|
||
|
And a not-yet-committed cleanup to clone.S.
|
||
|
---
|
||
|
ports/sysdeps/unix/sysv/linux/aarch64/clone.S | 51 +++---
|
||
|
ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S | 13 +-
|
||
|
.../unix/sysv/linux/aarch64/nptl/localplt.data | 1 -
|
||
|
.../unix/sysv/linux/aarch64/nptl/sysdep-cancel.h | 189 +++++++--------------
|
||
|
ports/sysdeps/unix/sysv/linux/aarch64/syscall.S | 4 +-
|
||
|
ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h | 84 ++-------
|
||
|
ports/sysdeps/unix/sysv/linux/aarch64/vfork.S | 4 +-
|
||
|
7 files changed, 108 insertions(+), 238 deletions(-)
|
||
|
|
||
|
diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/clone.S glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/clone.S
|
||
|
index 8be1464..d5c31f3 100644
|
||
|
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/clone.S
|
||
|
+++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/clone.S
|
||
|
@@ -39,46 +39,43 @@
|
||
|
*/
|
||
|
.text
|
||
|
ENTRY(__clone)
|
||
|
+ /* Save args for the child. */
|
||
|
+ mov x10, x0
|
||
|
+ mov x11, x2
|
||
|
+ mov x12, x3
|
||
|
+
|
||
|
/* Sanity check args. */
|
||
|
- cbz x0, 1f
|
||
|
- cbz x1, 1f
|
||
|
- /* Insert the args onto the new stack. */
|
||
|
- stp x0, x3, [x1, #-16]! /* Fn, arg. */
|
||
|
+ mov x0, #-EINVAL
|
||
|
+ cbz x10, .Lsyscall_error
|
||
|
+ cbz x1, .Lsyscall_error
|
||
|
|
||
|
/* Do the system call. */
|
||
|
+ /* X0:flags, x1:newsp, x2:parenttidptr, x3:newtls, x4:childtid. */
|
||
|
mov x0, x2 /* flags */
|
||
|
-
|
||
|
/* New sp is already in x1. */
|
||
|
mov x2, x4 /* ptid */
|
||
|
mov x3, x5 /* tls */
|
||
|
mov x4, x6 /* ctid */
|
||
|
|
||
|
-#ifdef RESET_PID
|
||
|
- /* We rely on the kernel preserving the argument regsiters across a
|
||
|
- each system call so that we can inspect the flags against after
|
||
|
- the clone call. */
|
||
|
- mov x5, x0
|
||
|
-#endif
|
||
|
-
|
||
|
mov x8, #SYS_ify(clone)
|
||
|
- /* X0:flags, x1:newsp, x2:parenttidptr, x3:newtls, x4:childtid. */
|
||
|
svc 0x0
|
||
|
- cfi_endproc
|
||
|
cmp x0, #0
|
||
|
- beq 2f
|
||
|
- blt C_SYMBOL_NAME(__syscall_error)
|
||
|
+ beq thread_start
|
||
|
+ blt .Lsyscall_error
|
||
|
RET
|
||
|
-1: mov x0, #-EINVAL
|
||
|
- b syscall_error
|
||
|
+PSEUDO_END (__clone)
|
||
|
|
||
|
-2:
|
||
|
+ .align 4
|
||
|
+ .type thread_start, %function
|
||
|
+thread_start:
|
||
|
cfi_startproc
|
||
|
cfi_undefined (x30)
|
||
|
mov x29, 0
|
||
|
+
|
||
|
#ifdef RESET_PID
|
||
|
- tbnz x5, #CLONE_THREAD_BIT, 3f
|
||
|
+ tbnz x11, #CLONE_THREAD_BIT, 3f
|
||
|
mov x0, #-1
|
||
|
- tbnz x5, #CLONE_VM_BIT, 2f
|
||
|
+ tbnz x11, #CLONE_VM_BIT, 2f
|
||
|
mov x8, #SYS_ify(getpid)
|
||
|
svc 0x0
|
||
|
2:
|
||
|
@@ -86,18 +83,16 @@ ENTRY(__clone)
|
||
|
sub x1, x1, #PTHREAD_SIZEOF
|
||
|
str w0, [x1, #PTHREAD_PID_OFFSET]
|
||
|
str w0, [x1, #PTHREAD_TID_OFFSET]
|
||
|
-
|
||
|
3:
|
||
|
#endif
|
||
|
- /* Pick the function arg and call address from the stack and
|
||
|
- execute. */
|
||
|
- ldp x1, x0, [sp], #16
|
||
|
- blr x1
|
||
|
+
|
||
|
+ /* Pick the function arg execute. */
|
||
|
+ mov x0, x12
|
||
|
+ blr x10
|
||
|
|
||
|
/* We are done, pass the return value through x0. */
|
||
|
b HIDDEN_JUMPTARGET(_exit)
|
||
|
cfi_endproc
|
||
|
- cfi_startproc
|
||
|
-PSEUDO_END (__clone)
|
||
|
+ .size thread_start, .-thread_start
|
||
|
|
||
|
weak_alias (__clone, clone)
|
||
|
diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S
|
||
|
index f01fb84..be6c026 100644
|
||
|
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S
|
||
|
+++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S
|
||
|
@@ -20,13 +20,12 @@
|
||
|
|
||
|
.text
|
||
|
ENTRY(__ioctl)
|
||
|
- movz x8, #__NR_ioctl
|
||
|
- sxtw x0, w0
|
||
|
- svc #0x0
|
||
|
- cmn x0, #0x1, lsl #12
|
||
|
- b.hi C_SYMBOL_NAME(__syscall_error)
|
||
|
+ mov x8, #__NR_ioctl
|
||
|
+ sxtw x0, w0
|
||
|
+ svc #0x0
|
||
|
+ cmn x0, #4095
|
||
|
+ b.cs .Lsyscall_error
|
||
|
ret
|
||
|
-
|
||
|
- PSEUDO_END (__ioctl)
|
||
|
+PSEUDO_END (__ioctl)
|
||
|
|
||
|
weak_alias (__ioctl, ioctl)
|
||
|
diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data
|
||
|
index 84af95d..dfca9a7 100644
|
||
|
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data
|
||
|
+++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data
|
||
|
@@ -12,4 +12,3 @@ libm.so: matherr
|
||
|
libm.so: __signbit
|
||
|
libm.so: __signbitf
|
||
|
libm.so: __signbitl
|
||
|
-libpthread.so: __errno_location
|
||
|
diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
|
||
|
index e0e5cc0..a3b9284 100644
|
||
|
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
|
||
|
+++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h
|
||
|
@@ -26,119 +26,60 @@
|
||
|
|
||
|
# undef PSEUDO
|
||
|
# define PSEUDO(name, syscall_name, args) \
|
||
|
- .section ".text"; \
|
||
|
- .type __##syscall_name##_nocancel,%function; \
|
||
|
- .globl __##syscall_name##_nocancel; \
|
||
|
- __##syscall_name##_nocancel: \
|
||
|
- cfi_startproc; \
|
||
|
- DO_CALL (syscall_name, args); \
|
||
|
- PSEUDO_RET; \
|
||
|
- cfi_endproc; \
|
||
|
- .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
|
||
|
- ENTRY (name); \
|
||
|
- SINGLE_THREAD_P; \
|
||
|
- DOARGS_##args; \
|
||
|
- bne .Lpseudo_cancel; \
|
||
|
- DO_CALL (syscall_name, 0); \
|
||
|
- UNDOARGS_##args; \
|
||
|
- cmn x0, 4095; \
|
||
|
- PSEUDO_RET; \
|
||
|
- .Lpseudo_cancel: \
|
||
|
- DOCARGS_##args; /* save syscall args etc. around CENABLE. */ \
|
||
|
- CENABLE; \
|
||
|
- mov x16, x0; /* put mask in safe place. */ \
|
||
|
- UNDOCARGS_##args; /* restore syscall args. */ \
|
||
|
- mov x8, SYS_ify (syscall_name); /* do the call. */ \
|
||
|
- svc 0; \
|
||
|
- str x0, [sp, -16]!; /* save syscall return value. */ \
|
||
|
- cfi_adjust_cfa_offset (16); \
|
||
|
- mov x0, x16; /* get mask back. */ \
|
||
|
- CDISABLE; \
|
||
|
- ldr x0, [sp], 16; \
|
||
|
- cfi_adjust_cfa_offset (-16); \
|
||
|
- ldr x30, [sp], 16; \
|
||
|
- cfi_adjust_cfa_offset (-16); \
|
||
|
- cfi_restore (x30); \
|
||
|
- UNDOARGS_##args; \
|
||
|
- cmn x0, 4095;
|
||
|
-
|
||
|
-# define DOCARGS_0 \
|
||
|
- str x30, [sp, -16]!; \
|
||
|
- cfi_adjust_cfa_offset (16); \
|
||
|
- cfi_rel_offset (x30, 0)
|
||
|
+ .section ".text"; \
|
||
|
+ENTRY (__##syscall_name##_nocancel); \
|
||
|
+.Lpseudo_nocancel: \
|
||
|
+ DO_CALL (syscall_name, args); \
|
||
|
+.Lpseudo_finish: \
|
||
|
+ cmn x0, 4095; \
|
||
|
+ b.cs .Lsyscall_error; \
|
||
|
+ .subsection 2; \
|
||
|
+ .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
|
||
|
+ENTRY (name); \
|
||
|
+ SINGLE_THREAD_P(16); \
|
||
|
+ cbz w16, .Lpseudo_nocancel; \
|
||
|
+ /* Setup common stack frame no matter the number of args. \
|
||
|
+ Also save the first arg, since it's basically free. */ \
|
||
|
+ stp x30, x0, [sp, -64]!; \
|
||
|
+ cfi_adjust_cfa_offset (64); \
|
||
|
+ cfi_rel_offset (x30, 0); \
|
||
|
+ DOCARGS_##args; /* save syscall args around CENABLE. */ \
|
||
|
+ CENABLE; \
|
||
|
+ mov x16, x0; /* save mask around syscall. */ \
|
||
|
+ UNDOCARGS_##args; /* restore syscall args. */ \
|
||
|
+ DO_CALL (syscall_name, args); \
|
||
|
+ str x0, [sp, 8]; /* save result around CDISABLE. */ \
|
||
|
+ mov x0, x16; /* restore mask for CDISABLE. */ \
|
||
|
+ CDISABLE; \
|
||
|
+ /* Break down the stack frame, restoring result at once. */ \
|
||
|
+ ldp x30, x0, [sp], 64; \
|
||
|
+ cfi_adjust_cfa_offset (-64); \
|
||
|
+ cfi_restore (x30); \
|
||
|
+ b .Lpseudo_finish; \
|
||
|
+ cfi_endproc; \
|
||
|
+ .size name, .-name; \
|
||
|
+ .previous
|
||
|
+
|
||
|
+# undef PSEUDO_END
|
||
|
+# define PSEUDO_END(name) \
|
||
|
+ SYSCALL_ERROR_HANDLER; \
|
||
|
+ cfi_endproc
|
||
|
+
|
||
|
+# define DOCARGS_0
|
||
|
+# define DOCARGS_1
|
||
|
+# define DOCARGS_2 str x1, [sp, 16]
|
||
|
+# define DOCARGS_3 stp x1, x2, [sp, 16]
|
||
|
+# define DOCARGS_4 DOCARGS_3; str x3, [sp, 32]
|
||
|
+# define DOCARGS_5 DOCARGS_3; stp x3, x4, [sp, 32]
|
||
|
+# define DOCARGS_6 DOCARGS_5; str x5, [sp, 48]
|
||
|
|
||
|
# define UNDOCARGS_0
|
||
|
-
|
||
|
-# define DOCARGS_1 \
|
||
|
- DOCARGS_0; \
|
||
|
- str x0, [sp, -16]!; \
|
||
|
- cfi_adjust_cfa_offset (16); \
|
||
|
- cfi_rel_offset (x0, 0)
|
||
|
-
|
||
|
-# define UNDOCARGS_1 \
|
||
|
- ldr x0, [sp], 16; \
|
||
|
- cfi_restore (x0); \
|
||
|
- cfi_adjust_cfa_offset (-16); \
|
||
|
-
|
||
|
-# define DOCARGS_2 \
|
||
|
- DOCARGS_1; \
|
||
|
- str x1, [sp, -16]!; \
|
||
|
- cfi_adjust_cfa_offset (16); \
|
||
|
- cfi_rel_offset (x1, 0)
|
||
|
-
|
||
|
-# define UNDOCARGS_2 \
|
||
|
- ldr x1, [sp], 16; \
|
||
|
- cfi_restore (x1); \
|
||
|
- cfi_adjust_cfa_offset (-16); \
|
||
|
- UNDOCARGS_1
|
||
|
-
|
||
|
-# define DOCARGS_3 \
|
||
|
- DOCARGS_2; \
|
||
|
- str x2, [sp, -16]!; \
|
||
|
- cfi_adjust_cfa_offset (16); \
|
||
|
- cfi_rel_offset (x2, 0)
|
||
|
-
|
||
|
-# define UNDOCARGS_3 \
|
||
|
- ldr x2, [sp], 16; \
|
||
|
- cfi_restore (x2); \
|
||
|
- cfi_adjust_cfa_offset (-16); \
|
||
|
- UNDOCARGS_2
|
||
|
-
|
||
|
-# define DOCARGS_4 \
|
||
|
- DOCARGS_3; \
|
||
|
- str x3, [sp, -16]!; \
|
||
|
- cfi_adjust_cfa_offset (16); \
|
||
|
- cfi_rel_offset (x3, 0)
|
||
|
-
|
||
|
-# define UNDOCARGS_4 \
|
||
|
- ldr x3, [sp], 16; \
|
||
|
- cfi_restore (x3); \
|
||
|
- cfi_adjust_cfa_offset (-16); \
|
||
|
- UNDOCARGS_3
|
||
|
-
|
||
|
-# define DOCARGS_5 \
|
||
|
- DOCARGS_4; \
|
||
|
- str x4, [sp, -16]!; \
|
||
|
- cfi_adjust_cfa_offset (16); \
|
||
|
- cfi_rel_offset (x4, 0)
|
||
|
-
|
||
|
-# define UNDOCARGS_5 \
|
||
|
- ldr x4, [sp], 16; \
|
||
|
- cfi_restore (x4); \
|
||
|
- cfi_adjust_cfa_offset (-16); \
|
||
|
- UNDOCARGS_4
|
||
|
-
|
||
|
-# define DOCARGS_6 \
|
||
|
- DOCARGS_5; \
|
||
|
- str x5, [sp, -16]!; \
|
||
|
- cfi_adjust_cfa_offset (16); \
|
||
|
- cfi_rel_offset (x5, 0)
|
||
|
-
|
||
|
-# define UNDOCARGS_6 \
|
||
|
- ldr x5, [sp], 16; \
|
||
|
- cfi_restore (x5); \
|
||
|
- cfi_adjust_cfa_offset (-16); \
|
||
|
- UNDOCARGS_5
|
||
|
+# define UNDOCARGS_1 ldr x0, [sp, 8]
|
||
|
+# define UNDOCARGS_2 ldp x0, x1, [sp, 8]
|
||
|
+# define UNDOCARGS_3 UNDOCARGS_1; ldp x1, x2, [sp, 16]
|
||
|
+# define UNDOCARGS_4 UNDOCARGS_2; ldp x2, x3, [sp, 24]
|
||
|
+# define UNDOCARGS_5 UNDOCARGS_3; ldp x3, x4, [sp, 32]
|
||
|
+# define UNDOCARGS_6 UNDOCARGS_4; ldp x4, x5, [sp, 40]
|
||
|
|
||
|
# ifdef IS_IN_libpthread
|
||
|
# define CENABLE bl __pthread_enable_asynccancel
|
||
|
@@ -160,11 +101,9 @@
|
||
|
extern int __local_multiple_threads attribute_hidden;
|
||
|
# define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
|
||
|
# else
|
||
|
-# define SINGLE_THREAD_P \
|
||
|
- adrp x16, __local_multiple_threads; \
|
||
|
- add x16, x16, #:lo12:__local_multiple_threads; \
|
||
|
- ldr x16, [x16]; \
|
||
|
- cmp x16, 0;
|
||
|
+# define SINGLE_THREAD_P(R) \
|
||
|
+ adrp x##R, __local_multiple_threads; \
|
||
|
+ ldr w##R, [x##R, :lo12:__local_multiple_threads]
|
||
|
# endif
|
||
|
# else
|
||
|
/* There is no __local_multiple_threads for librt, so use the TCB. */
|
||
|
@@ -173,20 +112,10 @@ extern int __local_multiple_threads attribute_hidden;
|
||
|
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||
|
header.multiple_threads) == 0, 1)
|
||
|
# else
|
||
|
-# define SINGLE_THREAD_P \
|
||
|
- stp x0, x30, [sp, -16]!; \
|
||
|
- cfi_adjust_cfa_offset (16); \
|
||
|
- cfi_rel_offset (x0, 0); \
|
||
|
- cfi_rel_offset (x30, 8); \
|
||
|
- bl __read_tp; \
|
||
|
- sub x0, x0, PTHREAD_SIZEOF; \
|
||
|
- ldr x16, [x0, PTHREAD_MULTIPLE_THREADS_OFFSET]; \
|
||
|
- ldp x0, x30, [sp], 16; \
|
||
|
- cfi_restore (x0); \
|
||
|
- cfi_restore (x30); \
|
||
|
- cfi_adjust_cfa_offset (-16); \
|
||
|
- cmp x16, 0
|
||
|
-# define SINGLE_THREAD_P_PIC(x) SINGLE_THREAD_P
|
||
|
+# define SINGLE_THREAD_P(R) \
|
||
|
+ mrs x##R, tpidr_el0; \
|
||
|
+ sub x##R, x##R, PTHREAD_SIZEOF; \
|
||
|
+ ldr w##R, [x##R, PTHREAD_MULTIPLE_THREADS_OFFSET]
|
||
|
# endif
|
||
|
# endif
|
||
|
|
||
|
diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/syscall.S glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/syscall.S
|
||
|
index 574fdf1..fac6416 100644
|
||
|
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/syscall.S
|
||
|
+++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/syscall.S
|
||
|
@@ -37,8 +37,6 @@ ENTRY (syscall)
|
||
|
mov x6, x7
|
||
|
svc 0x0
|
||
|
cmn x0, #4095
|
||
|
- b.cs 1f
|
||
|
+ b.cs .Lsyscall_error
|
||
|
RET
|
||
|
-1:
|
||
|
- b SYSCALL_ERROR
|
||
|
PSEUDO_END (syscall)
|
||
|
diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h
|
||
|
index 713bf7d..9961c03 100644
|
||
|
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h
|
||
|
+++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h
|
||
|
@@ -58,19 +58,8 @@
|
||
|
.text; \
|
||
|
ENTRY (name); \
|
||
|
DO_CALL (syscall_name, args); \
|
||
|
- cmn x0, #4095;
|
||
|
-
|
||
|
-/* Notice the use of 'RET' instead of 'ret' the assembler is case
|
||
|
- insensitive and eglibc already uses the preprocessor symbol 'ret'
|
||
|
- so we use the upper case 'RET' to force through a ret instruction
|
||
|
- to the assembler */
|
||
|
-# define PSEUDO_RET \
|
||
|
- b.cs 1f; \
|
||
|
- RET; \
|
||
|
- 1: \
|
||
|
- b SYSCALL_ERROR
|
||
|
-# undef ret
|
||
|
-# define ret PSEUDO_RET
|
||
|
+ cmn x0, #4095; \
|
||
|
+ b.cs .Lsyscall_error
|
||
|
|
||
|
# undef PSEUDO_END
|
||
|
# define PSEUDO_END(name) \
|
||
|
@@ -83,15 +72,7 @@
|
||
|
ENTRY (name); \
|
||
|
DO_CALL (syscall_name, args);
|
||
|
|
||
|
-/* Notice the use of 'RET' instead of 'ret' the assembler is case
|
||
|
- insensitive and eglibc already uses the preprocessor symbol 'ret'
|
||
|
- so we use the upper case 'RET' to force through a ret instruction
|
||
|
- to the assembler */
|
||
|
-# define PSEUDO_RET_NOERRNO \
|
||
|
- RET;
|
||
|
-
|
||
|
-# undef ret_NOERRNO
|
||
|
-# define ret_NOERRNO PSEUDO_RET_NOERRNO
|
||
|
+# define ret_NOERRNO ret
|
||
|
|
||
|
# undef PSEUDO_END_NOERRNO
|
||
|
# define PSEUDO_END_NOERRNO(name) \
|
||
|
@@ -109,47 +90,38 @@
|
||
|
# define PSEUDO_END_ERRVAL(name) \
|
||
|
END (name)
|
||
|
|
||
|
-# define ret_ERRVAL PSEUDO_RET_NOERRNO
|
||
|
+# define ret_ERRVAL ret
|
||
|
|
||
|
+# define SYSCALL_ERROR .Lsyscall_error
|
||
|
# if NOT_IN_libc
|
||
|
-# define SYSCALL_ERROR __local_syscall_error
|
||
|
# if RTLD_PRIVATE_ERRNO
|
||
|
# define SYSCALL_ERROR_HANDLER \
|
||
|
-__local_syscall_error: \
|
||
|
+.Lsyscall_error: \
|
||
|
adrp x1, C_SYMBOL_NAME(rtld_errno); \
|
||
|
- add x1, x1, #:lo12:C_SYMBOL_NAME(rtld_errno); \
|
||
|
neg w0, w0; \
|
||
|
- str w0, [x1]; \
|
||
|
+ str w0, [x1, :lo12:C_SYMBOL_NAME(rtld_errno)]; \
|
||
|
mov x0, -1; \
|
||
|
RET;
|
||
|
# else
|
||
|
|
||
|
# define SYSCALL_ERROR_HANDLER \
|
||
|
-__local_syscall_error: \
|
||
|
- stp x29, x30, [sp, -32]!; \
|
||
|
- cfi_adjust_cfa_offset (32); \
|
||
|
- cfi_rel_offset (x29, 0); \
|
||
|
- cfi_rel_offset (x30, 8); \
|
||
|
- add x29, sp, 0; \
|
||
|
- str x19, [sp,16]; \
|
||
|
- neg x19, x0; \
|
||
|
- bl C_SYMBOL_NAME(__errno_location); \
|
||
|
- str x19, [x0]; \
|
||
|
+.Lsyscall_error: \
|
||
|
+ adrp x1, :gottprel:errno; \
|
||
|
+ neg w2, w0; \
|
||
|
+ ldr x1, [x1, :gottprel_lo12:errno]; \
|
||
|
+ mrs x3, tpidr_el0; \
|
||
|
mov x0, -1; \
|
||
|
- ldr x19, [sp,16]; \
|
||
|
- ldp x29, x30, [sp], 32; \
|
||
|
- cfi_adjust_cfa_offset (-32); \
|
||
|
- cfi_restore (x29); \
|
||
|
- cfi_restore (x30); \
|
||
|
+ str w2, [x1, x3]; \
|
||
|
RET;
|
||
|
# endif
|
||
|
# else
|
||
|
-# define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */
|
||
|
-# define SYSCALL_ERROR __syscall_error
|
||
|
+# define SYSCALL_ERROR_HANDLER \
|
||
|
+.Lsyscall_error: \
|
||
|
+ b __syscall_error;
|
||
|
# endif
|
||
|
|
||
|
/* Linux takes system call args in registers:
|
||
|
- syscall number in the SVC instruction
|
||
|
+ syscall number x8
|
||
|
arg 1 x0
|
||
|
arg 2 x1
|
||
|
arg 3 x2
|
||
|
@@ -177,28 +149,8 @@ __local_syscall_error: \
|
||
|
|
||
|
# undef DO_CALL
|
||
|
# define DO_CALL(syscall_name, args) \
|
||
|
- DOARGS_##args \
|
||
|
mov x8, SYS_ify (syscall_name); \
|
||
|
- svc 0; \
|
||
|
- UNDOARGS_##args
|
||
|
-
|
||
|
-# define DOARGS_0 /* nothing */
|
||
|
-# define DOARGS_1 /* nothing */
|
||
|
-# define DOARGS_2 /* nothing */
|
||
|
-# define DOARGS_3 /* nothing */
|
||
|
-# define DOARGS_4 /* nothing */
|
||
|
-# define DOARGS_5 /* nothing */
|
||
|
-# define DOARGS_6 /* nothing */
|
||
|
-# define DOARGS_7 /* nothing */
|
||
|
-
|
||
|
-# define UNDOARGS_0 /* nothing */
|
||
|
-# define UNDOARGS_1 /* nothing */
|
||
|
-# define UNDOARGS_2 /* nothing */
|
||
|
-# define UNDOARGS_3 /* nothing */
|
||
|
-# define UNDOARGS_4 /* nothing */
|
||
|
-# define UNDOARGS_5 /* nothing */
|
||
|
-# define UNDOARGS_6 /* nothing */
|
||
|
-# define UNDOARGS_7 /* nothing */
|
||
|
+ svc 0
|
||
|
|
||
|
#else /* not __ASSEMBLER__ */
|
||
|
|
||
|
diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/vfork.S glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/vfork.S
|
||
|
index f2dc49b..3fb68b9 100644
|
||
|
--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/vfork.S
|
||
|
+++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/vfork.S
|
||
|
@@ -38,10 +38,8 @@ ENTRY (__vfork)
|
||
|
RESTORE_PID
|
||
|
#endif
|
||
|
cmn x0, #4095
|
||
|
- b.cs 1f
|
||
|
+ b.cs .Lsyscall_error
|
||
|
RET
|
||
|
-1:
|
||
|
- b SYSCALL_ERROR
|
||
|
|
||
|
PSEUDO_END (__vfork)
|
||
|
libc_hidden_def (__vfork)
|
||
|
--
|
||
|
1.8.3.1
|