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