1144 lines
36 KiB
Diff
1144 lines
36 KiB
Diff
From a48f11d0af793110f1a5289967bcb45a188058c3 Mon Sep 17 00:00:00 2001
|
|
From: swcompiler <lc@wxiat.com>
|
|
Date: Fri, 29 Nov 2024 14:04:40 +0800
|
|
Subject: [PATCH 07/23] Sw64: Linux Syscall Interface
|
|
|
|
---
|
|
sysdeps/unix/sw_64/Makefile | 4 +
|
|
sysdeps/unix/sw_64/pipe.S | 31 ++
|
|
sysdeps/unix/sw_64/rt-sysdep.S | 1 +
|
|
sysdeps/unix/sw_64/sysdep.S | 65 ++++
|
|
sysdeps/unix/sysv/linux/sw_64/arch-syscall.h | 376 +++++++++++++++++++
|
|
sysdeps/unix/sysv/linux/sw_64/clone.S | 117 ++++++
|
|
sysdeps/unix/sysv/linux/sw_64/syscall.S | 70 ++++
|
|
sysdeps/unix/sysv/linux/sw_64/sysdep.h | 355 +++++++++++++++++
|
|
sysdeps/unix/sysv/linux/sw_64/vfork.S | 41 ++
|
|
9 files changed, 1060 insertions(+)
|
|
create mode 100644 sysdeps/unix/sw_64/Makefile
|
|
create mode 100644 sysdeps/unix/sw_64/pipe.S
|
|
create mode 100644 sysdeps/unix/sw_64/rt-sysdep.S
|
|
create mode 100644 sysdeps/unix/sw_64/sysdep.S
|
|
create mode 100644 sysdeps/unix/sysv/linux/sw_64/arch-syscall.h
|
|
create mode 100644 sysdeps/unix/sysv/linux/sw_64/clone.S
|
|
create mode 100644 sysdeps/unix/sysv/linux/sw_64/syscall.S
|
|
create mode 100644 sysdeps/unix/sysv/linux/sw_64/sysdep.h
|
|
create mode 100644 sysdeps/unix/sysv/linux/sw_64/vfork.S
|
|
|
|
diff --git a/sysdeps/unix/sw_64/Makefile b/sysdeps/unix/sw_64/Makefile
|
|
new file mode 100644
|
|
index 00000000..0660847f
|
|
--- /dev/null
|
|
+++ b/sysdeps/unix/sw_64/Makefile
|
|
@@ -0,0 +1,4 @@
|
|
+ifeq ($(subdir),rt)
|
|
+librt-sysdep_routines += rt-sysdep
|
|
+librt-shared-only-routines += rt-sysdep
|
|
+endif
|
|
diff --git a/sysdeps/unix/sw_64/pipe.S b/sysdeps/unix/sw_64/pipe.S
|
|
new file mode 100644
|
|
index 00000000..d851fe17
|
|
--- /dev/null
|
|
+++ b/sysdeps/unix/sw_64/pipe.S
|
|
@@ -0,0 +1,31 @@
|
|
+/* Copyright (C) 1993-2023 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+ Contributed by David Mosberger (davidm@cs.arizona.edu).
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library. If not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+/* __pipe is a special syscall since it returns two values. */
|
|
+
|
|
+#include <sysdep.h>
|
|
+
|
|
+PSEUDO (__pipe, pipe, 0)
|
|
+ stw r0, 0(a0)
|
|
+ stw r1, 4(a0)
|
|
+ mov zero, v0
|
|
+ ret
|
|
+PSEUDO_END(__pipe)
|
|
+
|
|
+libc_hidden_def (__pipe)
|
|
+weak_alias (__pipe, pipe)
|
|
diff --git a/sysdeps/unix/sw_64/rt-sysdep.S b/sysdeps/unix/sw_64/rt-sysdep.S
|
|
new file mode 100644
|
|
index 00000000..f966bf1e
|
|
--- /dev/null
|
|
+++ b/sysdeps/unix/sw_64/rt-sysdep.S
|
|
@@ -0,0 +1 @@
|
|
+#include <sysdep.S>
|
|
diff --git a/sysdeps/unix/sw_64/sysdep.S b/sysdeps/unix/sw_64/sysdep.S
|
|
new file mode 100644
|
|
index 00000000..306184c3
|
|
--- /dev/null
|
|
+++ b/sysdeps/unix/sw_64/sysdep.S
|
|
@@ -0,0 +1,65 @@
|
|
+/* Copyright (C) 1993-2023 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+ Contributed by Brendan Kehoe (brendan@zen.org).
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library. If not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#include <sysdep.h>
|
|
+#include <features.h>
|
|
+
|
|
+#if defined(PIC)
|
|
+ /* Put this at the end of libc's text segment so that all of
|
|
+ the direct branches from the syscalls are forward, and
|
|
+ thus predicted not taken. */
|
|
+ .section .text.last, "ax", @progbits
|
|
+#else
|
|
+ .text
|
|
+#endif
|
|
+
|
|
+#if IS_IN (libc)
|
|
+# define SYSCALL_ERROR_ERRNO __libc_errno
|
|
+#else
|
|
+# define SYSCALL_ERROR_ERRNO errno
|
|
+#endif
|
|
+
|
|
+ .align 4
|
|
+ .globl __syscall_error
|
|
+ .ent __syscall_error
|
|
+__syscall_error:
|
|
+ /* When building a shared library, we branch here without having
|
|
+ loaded the GP. Nor, since it was a direct branch, have we
|
|
+ loaded PV with our address.
|
|
+
|
|
+ When building a static library, we tail call here from another
|
|
+ object file, possibly with a different GP, and must return with
|
|
+ the GP of our caller in place so that linker relaxation works.
|
|
+
|
|
+ Both issues are solved by computing the GP into T1 instead of
|
|
+ clobbering the traditional GP register. */
|
|
+ .prologue 0
|
|
+ mov v0, t0
|
|
+ br t1, 1f
|
|
+1: ldih t1, 0(t1) !gpdisp!1
|
|
+ sys_call HMC_rdunique
|
|
+
|
|
+ ldi t1, 0(t1) !gpdisp!1
|
|
+ ldl t1, SYSCALL_ERROR_ERRNO(t1) !gottprel
|
|
+ addl v0, t1, t1
|
|
+ ldi v0, -1
|
|
+
|
|
+ stw t0, 0(t1)
|
|
+ ret
|
|
+
|
|
+ .end __syscall_error
|
|
diff --git a/sysdeps/unix/sysv/linux/sw_64/arch-syscall.h b/sysdeps/unix/sysv/linux/sw_64/arch-syscall.h
|
|
new file mode 100644
|
|
index 00000000..62597a14
|
|
--- /dev/null
|
|
+++ b/sysdeps/unix/sysv/linux/sw_64/arch-syscall.h
|
|
@@ -0,0 +1,376 @@
|
|
+/* AUTOGENERATED by update-syscall-lists.py. */
|
|
+#define __NR_accept 99
|
|
+#define __NR_accept4 502
|
|
+#define __NR_access 33
|
|
+#define __NR_acct 51
|
|
+#define __NR_add_key 439
|
|
+#define __NR_adjtimex 366
|
|
+#define __NR_afs_syscall 338
|
|
+#define __NR_bdflush 300
|
|
+#define __NR_bind 104
|
|
+#define __NR_bpf 170
|
|
+#define __NR_brk 17
|
|
+#define __NR_cachestat 190
|
|
+#define __NR_capget 368
|
|
+#define __NR_capset 369
|
|
+#define __NR_chdir 12
|
|
+#define __NR_chmod 15
|
|
+#define __NR_chown 16
|
|
+#define __NR_chroot 61
|
|
+#define __NR_clock_adjtime 499
|
|
+#define __NR_clock_getres 421
|
|
+#define __NR_clock_gettime 420
|
|
+#define __NR_clock_nanosleep 422
|
|
+#define __NR_clock_settime 419
|
|
+#define __NR_clone 312
|
|
+#define __NR_clone3 282
|
|
+#define __NR_close 6
|
|
+#define __NR_close_range 283
|
|
+#define __NR_connect 98
|
|
+#define __NR_copy_file_range 515
|
|
+#define __NR_create_module 306
|
|
+#define __NR_delete_module 308
|
|
+#define __NR_dipc 373
|
|
+#define __NR_dup 41
|
|
+#define __NR_dup2 90
|
|
+#define __NR_dup3 487
|
|
+#define __NR_epoll_create 407
|
|
+#define __NR_epoll_create1 486
|
|
+#define __NR_epoll_ctl 408
|
|
+#define __NR_epoll_pwait 474
|
|
+#define __NR_epoll_pwait2 180
|
|
+#define __NR_epoll_wait 409
|
|
+#define __NR_eventfd 478
|
|
+#define __NR_eventfd2 485
|
|
+#define __NR_execve 59
|
|
+#define __NR_execveat 513
|
|
+#define __NR_exit 1
|
|
+#define __NR_exit_group 405
|
|
+#define __NR_faccessat 462
|
|
+#define __NR_faccessat2 286
|
|
+#define __NR_fadvise64 413
|
|
+#define __NR_fallocate 480
|
|
+#define __NR_fanotify_init 494
|
|
+#define __NR_fanotify_mark 495
|
|
+#define __NR_fchdir 13
|
|
+#define __NR_fchmod 124
|
|
+#define __NR_fchmodat 461
|
|
+#define __NR_fchmodat2 191
|
|
+#define __NR_fchown 123
|
|
+#define __NR_fchownat 453
|
|
+#define __NR_fcntl 92
|
|
+#define __NR_fdatasync 447
|
|
+#define __NR_fgetxattr 387
|
|
+#define __NR_finit_module 507
|
|
+#define __NR_flistxattr 390
|
|
+#define __NR_flock 131
|
|
+#define __NR_fork 2
|
|
+#define __NR_fremovexattr 393
|
|
+#define __NR_fsconfig 278
|
|
+#define __NR_fsetxattr 384
|
|
+#define __NR_fsmount 279
|
|
+#define __NR_fsopen 277
|
|
+#define __NR_fspick 280
|
|
+#define __NR_fstat 91
|
|
+#define __NR_fstat64 427
|
|
+#define __NR_fstatat64 455
|
|
+#define __NR_fstatfs 329
|
|
+#define __NR_fstatfs64 230
|
|
+#define __NR_fsync 95
|
|
+#define __NR_ftruncate 130
|
|
+#define __NR_futex 394
|
|
+#define __NR_futex_waitv 188
|
|
+#define __NR_futimesat 454
|
|
+#define __NR_get_kernel_syms 309
|
|
+#define __NR_get_mempolicy 430
|
|
+#define __NR_get_robust_list 467
|
|
+#define __NR_getcpu 473
|
|
+#define __NR_getcwd 367
|
|
+#define __NR_getdents 305
|
|
+#define __NR_getdents64 377
|
|
+#define __NR_getegid 179
|
|
+#define __NR_geteuid 177
|
|
+#define __NR_getgid 178
|
|
+#define __NR_getgroups 79
|
|
+#define __NR_gethostname 87
|
|
+#define __NR_getitimer 361
|
|
+#define __NR_getpeername 141
|
|
+#define __NR_getpgid 233
|
|
+#define __NR_getpgrp 63
|
|
+#define __NR_getpid 174
|
|
+#define __NR_getppid 175
|
|
+#define __NR_getpriority 298
|
|
+#define __NR_getrandom 511
|
|
+#define __NR_getresgid 372
|
|
+#define __NR_getresuid 344
|
|
+#define __NR_getrlimit 144
|
|
+#define __NR_getrusage 364
|
|
+#define __NR_getsid 234
|
|
+#define __NR_getsockname 150
|
|
+#define __NR_getsockopt 118
|
|
+#define __NR_getsysinfo 256
|
|
+#define __NR_gettid 378
|
|
+#define __NR_gettimeofday 359
|
|
+#define __NR_getuid 176
|
|
+#define __NR_getxattr 385
|
|
+#define __NR_getxgid 47
|
|
+#define __NR_getxpid 20
|
|
+#define __NR_getxuid 24
|
|
+#define __NR_init_module 307
|
|
+#define __NR_inotify_add_watch 445
|
|
+#define __NR_inotify_init 444
|
|
+#define __NR_inotify_init1 489
|
|
+#define __NR_inotify_rm_watch 446
|
|
+#define __NR_io_cancel 402
|
|
+#define __NR_io_destroy 399
|
|
+#define __NR_io_getevents 400
|
|
+#define __NR_io_pgetevents 403
|
|
+#define __NR_io_setup 398
|
|
+#define __NR_io_submit 401
|
|
+#define __NR_io_uring_enter 273
|
|
+#define __NR_io_uring_register 274
|
|
+#define __NR_io_uring_setup 272
|
|
+#define __NR_ioctl 54
|
|
+#define __NR_ioprio_get 443
|
|
+#define __NR_ioprio_set 442
|
|
+#define __NR_kcmp 506
|
|
+#define __NR_kexec_load 448
|
|
+#define __NR_keyctl 441
|
|
+#define __NR_kill 37
|
|
+#define __NR_landlock_add_rule 184
|
|
+#define __NR_landlock_create_ruleset 183
|
|
+#define __NR_landlock_restrict_self 185
|
|
+#define __NR_lchown 208
|
|
+#define __NR_lgetxattr 386
|
|
+#define __NR_link 9
|
|
+#define __NR_linkat 458
|
|
+#define __NR_listen 106
|
|
+#define __NR_listxattr 388
|
|
+#define __NR_llistxattr 389
|
|
+#define __NR_lookup_dcookie 406
|
|
+#define __NR_lremovexattr 392
|
|
+#define __NR_lseek 19
|
|
+#define __NR_lsetxattr 383
|
|
+#define __NR_lstat 68
|
|
+#define __NR_lstat64 426
|
|
+#define __NR_madvise 75
|
|
+#define __NR_mbind 429
|
|
+#define __NR_membarrier 172
|
|
+#define __NR_memfd_create 512
|
|
+#define __NR_migrate_pages 449
|
|
+#define __NR_mincore 375
|
|
+#define __NR_mkdir 136
|
|
+#define __NR_mkdirat 451
|
|
+#define __NR_mknod 14
|
|
+#define __NR_mknodat 452
|
|
+#define __NR_mlock 314
|
|
+#define __NR_mlock2 173
|
|
+#define __NR_mlockall 316
|
|
+#define __NR_mmap 71
|
|
+#define __NR_mount 302
|
|
+#define __NR_mount_setattr 181
|
|
+#define __NR_move_mount 276
|
|
+#define __NR_move_pages 472
|
|
+#define __NR_mprotect 74
|
|
+#define __NR_mq_getsetattr 437
|
|
+#define __NR_mq_notify 436
|
|
+#define __NR_mq_open 432
|
|
+#define __NR_mq_timedreceive 435
|
|
+#define __NR_mq_timedsend 434
|
|
+#define __NR_mq_unlink 433
|
|
+#define __NR_mremap 341
|
|
+#define __NR_msgctl 200
|
|
+#define __NR_msgget 201
|
|
+#define __NR_msgrcv 202
|
|
+#define __NR_msgsnd 203
|
|
+#define __NR_msync 217
|
|
+#define __NR_munlock 315
|
|
+#define __NR_munlockall 317
|
|
+#define __NR_munmap 73
|
|
+#define __NR_name_to_handle_at 497
|
|
+#define __NR_nanosleep 340
|
|
+#define __NR_nfsservctl 342
|
|
+#define __NR_odd_getpriority 100
|
|
+#define __NR_odd_sigprocmask 48
|
|
+#define __NR_oldumount 321
|
|
+#define __NR_open 45
|
|
+#define __NR_open_by_handle_at 498
|
|
+#define __NR_open_tree 275
|
|
+#define __NR_openat 450
|
|
+#define __NR_openat2 284
|
|
+#define __NR_pciconfig_iobase 376
|
|
+#define __NR_pciconfig_read 345
|
|
+#define __NR_pciconfig_write 346
|
|
+#define __NR_perf_event_open 493
|
|
+#define __NR_personality 324
|
|
+#define __NR_pidfd_getfd 285
|
|
+#define __NR_pidfd_open 281
|
|
+#define __NR_pidfd_send_signal 271
|
|
+#define __NR_pipe 42
|
|
+#define __NR_pipe2 488
|
|
+#define __NR_pivot_root 374
|
|
+#define __NR_pkey_alloc 289
|
|
+#define __NR_pkey_free 290
|
|
+#define __NR_pkey_mprotect 288
|
|
+#define __NR_poll 94
|
|
+#define __NR_ppoll 464
|
|
+#define __NR_prctl 348
|
|
+#define __NR_pread64 349
|
|
+#define __NR_preadv 490
|
|
+#define __NR_preadv2 516
|
|
+#define __NR_prlimit64 496
|
|
+#define __NR_process_madvise 287
|
|
+#define __NR_process_mrelease 187
|
|
+#define __NR_process_vm_readv 504
|
|
+#define __NR_process_vm_writev 505
|
|
+#define __NR_pselect6 463
|
|
+#define __NR_ptrace 26
|
|
+#define __NR_pwrite64 350
|
|
+#define __NR_pwritev 491
|
|
+#define __NR_pwritev2 517
|
|
+#define __NR_query_module 347
|
|
+#define __NR_quotactl 148
|
|
+#define __NR_quotactl_fd 182
|
|
+#define __NR_read 3
|
|
+#define __NR_readahead 379
|
|
+#define __NR_readlink 58
|
|
+#define __NR_readlinkat 460
|
|
+#define __NR_readv 120
|
|
+#define __NR_reboot 311
|
|
+#define __NR_recv 102
|
|
+#define __NR_recvfrom 125
|
|
+#define __NR_recvmmsg 479
|
|
+#define __NR_recvmsg 113
|
|
+#define __NR_remap_file_pages 410
|
|
+#define __NR_removexattr 391
|
|
+#define __NR_rename 128
|
|
+#define __NR_renameat 457
|
|
+#define __NR_renameat2 510
|
|
+#define __NR_request_key 440
|
|
+#define __NR_restart_syscall 412
|
|
+#define __NR_rmdir 137
|
|
+#define __NR_rseq 404
|
|
+#define __NR_rt_sigaction 352
|
|
+#define __NR_rt_sigpending 354
|
|
+#define __NR_rt_sigprocmask 353
|
|
+#define __NR_rt_sigqueueinfo 356
|
|
+#define __NR_rt_sigreturn 351
|
|
+#define __NR_rt_sigsuspend 357
|
|
+#define __NR_rt_sigtimedwait 355
|
|
+#define __NR_rt_tgsigqueueinfo 492
|
|
+#define __NR_sched_get_priority_max 335
|
|
+#define __NR_sched_get_priority_min 336
|
|
+#define __NR_sched_getaffinity 396
|
|
+#define __NR_sched_getattr 509
|
|
+#define __NR_sched_getparam 331
|
|
+#define __NR_sched_getscheduler 333
|
|
+#define __NR_sched_rr_get_interval 337
|
|
+#define __NR_sched_setaffinity 395
|
|
+#define __NR_sched_setattr 508
|
|
+#define __NR_sched_setparam 330
|
|
+#define __NR_sched_setscheduler 332
|
|
+#define __NR_sched_yield 334
|
|
+#define __NR_seccomp 514
|
|
+#define __NR_select 358
|
|
+#define __NR_semctl 204
|
|
+#define __NR_semget 205
|
|
+#define __NR_semop 206
|
|
+#define __NR_semtimedop 423
|
|
+#define __NR_send 101
|
|
+#define __NR_sendfile 370
|
|
+#define __NR_sendmmsg 503
|
|
+#define __NR_sendmsg 114
|
|
+#define __NR_sendto 133
|
|
+#define __NR_set_mempolicy 431
|
|
+#define __NR_set_mempolicy_home_node 189
|
|
+#define __NR_set_robust_list 466
|
|
+#define __NR_set_tid_address 411
|
|
+#define __NR_setdomainname 166
|
|
+#define __NR_setfsgid 326
|
|
+#define __NR_setfsuid 325
|
|
+#define __NR_setgid 132
|
|
+#define __NR_setgroups 80
|
|
+#define __NR_sethostname 88
|
|
+#define __NR_setitimer 362
|
|
+#define __NR_setns 501
|
|
+#define __NR_setpgid 39
|
|
+#define __NR_setpgrp 82
|
|
+#define __NR_setpriority 96
|
|
+#define __NR_setregid 127
|
|
+#define __NR_setresgid 371
|
|
+#define __NR_setresuid 343
|
|
+#define __NR_setreuid 126
|
|
+#define __NR_setrlimit 145
|
|
+#define __NR_setsid 147
|
|
+#define __NR_setsockopt 105
|
|
+#define __NR_setsysinfo 257
|
|
+#define __NR_settimeofday 360
|
|
+#define __NR_setuid 23
|
|
+#define __NR_setxattr 382
|
|
+#define __NR_shmat 209
|
|
+#define __NR_shmctl 210
|
|
+#define __NR_shmdt 211
|
|
+#define __NR_shmget 212
|
|
+#define __NR_shutdown 134
|
|
+#define __NR_sigaction 156
|
|
+#define __NR_sigaltstack 235
|
|
+#define __NR_signalfd 476
|
|
+#define __NR_signalfd4 484
|
|
+#define __NR_sigpending 52
|
|
+#define __NR_sigprocmask 299
|
|
+#define __NR_sigreturn 103
|
|
+#define __NR_sigsuspend 111
|
|
+#define __NR_socket 97
|
|
+#define __NR_socketcall 119
|
|
+#define __NR_socketpair 135
|
|
+#define __NR_splice 468
|
|
+#define __NR_stat 67
|
|
+#define __NR_stat64 425
|
|
+#define __NR_statfs 328
|
|
+#define __NR_statfs64 229
|
|
+#define __NR_statx 518
|
|
+#define __NR_swapoff 304
|
|
+#define __NR_swapon 322
|
|
+#define __NR_symlink 57
|
|
+#define __NR_symlinkat 459
|
|
+#define __NR_sync 36
|
|
+#define __NR_sync_file_range 469
|
|
+#define __NR_syncfs 500
|
|
+#define __NR_sysfs 254
|
|
+#define __NR_sysinfo 318
|
|
+#define __NR_syslog 310
|
|
+#define __NR_tee 470
|
|
+#define __NR_tgkill 424
|
|
+#define __NR_timer_create 414
|
|
+#define __NR_timer_delete 418
|
|
+#define __NR_timer_getoverrun 417
|
|
+#define __NR_timer_gettime 416
|
|
+#define __NR_timer_settime 415
|
|
+#define __NR_timerfd 477
|
|
+#define __NR_timerfd_create 481
|
|
+#define __NR_timerfd_gettime 483
|
|
+#define __NR_timerfd_settime 482
|
|
+#define __NR_times 323
|
|
+#define __NR_tkill 381
|
|
+#define __NR_truncate 129
|
|
+#define __NR_tuxcall 397
|
|
+#define __NR_umask 60
|
|
+#define __NR_umount 22
|
|
+#define __NR_umount2 22
|
|
+#define __NR_uname 339
|
|
+#define __NR_unlink 10
|
|
+#define __NR_unlinkat 456
|
|
+#define __NR_unshare 465
|
|
+#define __NR_uselib 313
|
|
+#define __NR_userfaultfd 171
|
|
+#define __NR_ustat 327
|
|
+#define __NR_utimensat 475
|
|
+#define __NR_utimes 363
|
|
+#define __NR_vfork 66
|
|
+#define __NR_vhangup 76
|
|
+#define __NR_vmsplice 471
|
|
+#define __NR_vserver 428
|
|
+#define __NR_wait4 365
|
|
+#define __NR_waitid 438
|
|
+#define __NR_write 4
|
|
+#define __NR_writev 121
|
|
diff --git a/sysdeps/unix/sysv/linux/sw_64/clone.S b/sysdeps/unix/sysv/linux/sw_64/clone.S
|
|
new file mode 100644
|
|
index 00000000..6f08adae
|
|
--- /dev/null
|
|
+++ b/sysdeps/unix/sysv/linux/sw_64/clone.S
|
|
@@ -0,0 +1,117 @@
|
|
+/* Copyright (C) 1996-2023 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+ Contributed by Richard Henderson <rth@tamu.edu>, 1996.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library. If not, see
|
|
+ <http://www.gnu.org/licenses/>. */
|
|
+
|
|
+/* clone() is even more special than fork() as it mucks with stacks
|
|
+ and invokes a function in the right context after its all over. */
|
|
+
|
|
+#include <sysdep.h>
|
|
+#define _ERRNO_H 1
|
|
+#include <bits/errno.h>
|
|
+
|
|
+/* int clone(int (*fn)(void *arg), void *child_stack, int flags,
|
|
+ void *arg, pid_t *ptid, void *tls, pid_t *ctid);
|
|
+
|
|
+ Note that everything past ARG is technically optional, based
|
|
+ on FLAGS, and that CTID is arg 7, and thus is on the stack.
|
|
+ However, since a load from top-of-stack better be legal always,
|
|
+ we don't bother checking FLAGS. */
|
|
+
|
|
+ .text
|
|
+ .align 4
|
|
+ .globl __clone
|
|
+ .ent __clone
|
|
+ .usepv __clone, USEPV_PROF
|
|
+
|
|
+ cfi_startproc
|
|
+__clone:
|
|
+#ifdef PROF
|
|
+ .set noat
|
|
+ ldgp gp,0(pv)
|
|
+ ldi AT, _mcount
|
|
+ call AT, (AT), _mcount
|
|
+ .set at
|
|
+#endif
|
|
+
|
|
+ /* Sanity check arguments. */
|
|
+ ldi v0, EINVAL
|
|
+ beq a0, SYSCALL_ERROR_LABEL /* no NULL function pointers */
|
|
+ bic a1, 0xf,a1 /*Align sp. By zyl */
|
|
+ beq a1, SYSCALL_ERROR_LABEL /* no NULL stack pointers */
|
|
+
|
|
+ /* Save the fn ptr and arg on the new stack. */
|
|
+ subl a1, 32, a1
|
|
+ stl a0, 0(a1)
|
|
+ stl a3, 8(a1)
|
|
+ stl a2, 16(a1)
|
|
+
|
|
+ /* The syscall is of the form clone(flags, usp, ptid, ctid, tls).
|
|
+ Shift the flags, ptid, ctid, tls arguments into place; the
|
|
+ child_stack argument is already correct. */
|
|
+ mov a2, a0
|
|
+ mov a4, a2
|
|
+ ldl a3, 0(sp)
|
|
+ mov a5, a4
|
|
+
|
|
+ /* Do the system call. */
|
|
+ ldi v0, __NR_clone
|
|
+ sys_call HMC_callsys
|
|
+
|
|
+ bne a3, SYSCALL_ERROR_LABEL
|
|
+ beq v0, thread_start
|
|
+
|
|
+ /* Successful return from the parent. */
|
|
+ ret
|
|
+
|
|
+PSEUDO_END(__clone)
|
|
+ cfi_endproc
|
|
+
|
|
+/* Load up the arguments to the function. Put this block of code in
|
|
+ its own function so that we can terminate the stack trace with our
|
|
+ debug info. */
|
|
+
|
|
+ .align 4
|
|
+ .ent thread_start
|
|
+ cfi_startproc
|
|
+thread_start:
|
|
+ mov 0, fp
|
|
+ cfi_def_cfa_register(fp)
|
|
+ cfi_undefined(ra)
|
|
+
|
|
+ /* Load up the arguments. */
|
|
+ ldl pv, 0(sp)
|
|
+ ldl a0, 8(sp)
|
|
+ addl sp, 32, sp
|
|
+
|
|
+ /* Call the user's function. */
|
|
+ call ra, (pv)
|
|
+ ldgp gp, 0(ra)
|
|
+
|
|
+ mov v0, a0
|
|
+ ldi v0, __NR_exit
|
|
+ sys_call HMC_callsys
|
|
+
|
|
+ /* Die horribly. */
|
|
+ .align 4
|
|
+ halt
|
|
+
|
|
+ .align 4
|
|
+ cfi_endproc
|
|
+ .end thread_start
|
|
+
|
|
+libc_hidden_def (__clone)
|
|
+weak_alias (__clone, clone)
|
|
diff --git a/sysdeps/unix/sysv/linux/sw_64/syscall.S b/sysdeps/unix/sysv/linux/sw_64/syscall.S
|
|
new file mode 100644
|
|
index 00000000..286b9925
|
|
--- /dev/null
|
|
+++ b/sysdeps/unix/sysv/linux/sw_64/syscall.S
|
|
@@ -0,0 +1,70 @@
|
|
+/* Copyright (C) 1996-2023 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+ Contributed by David Mosberger <davidm@azstarnet.com>, 1996.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library. If not, see
|
|
+ <http://www.gnu.org/licenses/>. */
|
|
+
|
|
+#include <sysdep.h>
|
|
+
|
|
+/*
|
|
+ * This is for COMPATIBILITY with Linux/x86 only. Linux/Sw_64 system
|
|
+ * calls return an error indication in a3. This allows arbitrary 64bit
|
|
+ * values to be returned in v0 (because negative values are not
|
|
+ * mistaken as error numbers). However, C allows only one value to
|
|
+ * be returned, so the interface below foflds the error indication passed in
|
|
+ * a3 back into v0: it sets v0 to -errno if an error occurs. Thus,
|
|
+ * no negative 64bit numbers can be returned. To avoid this problem,
|
|
+ * use assembly stubs wherever possible/convenient.
|
|
+ *
|
|
+ * Usage:
|
|
+ *
|
|
+ * long syscall(syscall_number, arg1, arg2, arg3, arg4, arg5, arg6)
|
|
+ *
|
|
+ * syscall_number = the index of the system call we're invoking
|
|
+ * arg1-arg6 = up to 6 integer arguments to the system call
|
|
+ *
|
|
+ * We need to do some arg shifting: the kernel expects the
|
|
+ * syscall number in v0 and the first six args in a0-a5.
|
|
+ *
|
|
+ */
|
|
+
|
|
+
|
|
+LEAF(__syscall, 0)
|
|
+#ifdef PROF
|
|
+ ldgp gp, 0(pv)
|
|
+ .set noat
|
|
+ ldi AT, _mcount
|
|
+ call AT, (AT), _mcount
|
|
+ .set at
|
|
+ .prologue 1
|
|
+#else
|
|
+ .prologue 0
|
|
+#endif
|
|
+
|
|
+ mov a0, v0 /* Syscall number -> v0 */
|
|
+ mov a1, a0 /* arg1-arg5 -> a0-a4 */
|
|
+ mov a2, a1
|
|
+ mov a3, a2
|
|
+ mov a4, a3
|
|
+ mov a5, a4
|
|
+ ldl a5,0(sp) /* arg6 -> a5 */
|
|
+
|
|
+ sys_call HMC_callsys /* Invoke system call */
|
|
+ bne a3, SYSCALL_ERROR_LABEL
|
|
+ ret
|
|
+
|
|
+PSEUDO_END(__syscall)
|
|
+
|
|
+weak_alias (__syscall, syscall)
|
|
diff --git a/sysdeps/unix/sysv/linux/sw_64/sysdep.h b/sysdeps/unix/sysv/linux/sw_64/sysdep.h
|
|
new file mode 100644
|
|
index 00000000..f047c609
|
|
--- /dev/null
|
|
+++ b/sysdeps/unix/sysv/linux/sw_64/sysdep.h
|
|
@@ -0,0 +1,355 @@
|
|
+/* Copyright (C) 1992-2023 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+ Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>, August 1995.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library. If not, see
|
|
+ <https://www.gnu.org/licenses/>. */
|
|
+
|
|
+#ifndef _LINUX_SW_64_SYSDEP_H
|
|
+#define _LINUX_SW_64_SYSDEP_H 1
|
|
+
|
|
+/* There is some commonality. */
|
|
+#include <sysdeps/unix/sysv/linux/sysdep.h>
|
|
+#include <sysdeps/unix/sysdep.h>
|
|
+#include <dl-sysdep.h> /* Defines RTLD_PRIVATE_ERRNO. */
|
|
+
|
|
+#include <tls.h>
|
|
+
|
|
+/* For Linux we can use the system call table in the header file
|
|
+ /usr/include/asm/unistd.h
|
|
+ of the kernel. But these symbols do not follow the SYS_* syntax
|
|
+ so we have to redefine the `SYS_ify' macro here. */
|
|
+#undef SYS_ify
|
|
+#define SYS_ify(syscall_name) __NR_##syscall_name
|
|
+
|
|
+#define SINGLE_THREAD_BY_GLOBAL 1
|
|
+
|
|
+#ifdef __ASSEMBLER__
|
|
+# include <asm/hmcall.h>
|
|
+# include <sw_64/regdef.h>
|
|
+
|
|
+# define __LABEL(x) x##:
|
|
+
|
|
+# define LEAF(name, framesize) \
|
|
+ .globl name; \
|
|
+ .align 4; \
|
|
+ .ent name, 0; \
|
|
+ __LABEL (name).frame sp, framesize, ra
|
|
+
|
|
+# define ENTRY(name) \
|
|
+ .globl name; \
|
|
+ .align 4; \
|
|
+ .ent name, 0; \
|
|
+ __LABEL (name).frame sp, 0, ra
|
|
+
|
|
+/* Mark the end of function SYM. */
|
|
+# undef END
|
|
+# define END(sym) .end sym
|
|
+
|
|
+# ifdef PROF
|
|
+# define PSEUDO_PROF \
|
|
+ .set noat; \
|
|
+ ldi AT, _mcount; \
|
|
+ call AT, (AT), _mcount; \
|
|
+ .set at
|
|
+# else
|
|
+# define PSEUDO_PROF
|
|
+# endif
|
|
+
|
|
+# ifdef PROF
|
|
+# define PSEUDO_PROLOGUE \
|
|
+ .frame sp, 0, ra; \
|
|
+ ldgp gp, 0(pv); \
|
|
+ PSEUDO_PROF; \
|
|
+ .prologue 1
|
|
+# elif defined PIC
|
|
+# define PSEUDO_PROLOGUE \
|
|
+ .frame sp, 0, ra; \
|
|
+ .prologue 0
|
|
+# else
|
|
+# define PSEUDO_PROLOGUE \
|
|
+ .frame sp, 0, ra; \
|
|
+ ldgp gp, 0(pv); \
|
|
+ .prologue 1
|
|
+# endif /* PROF */
|
|
+
|
|
+# ifdef PROF
|
|
+# define USEPV_PROF std
|
|
+# else
|
|
+# define USEPV_PROF no
|
|
+# endif
|
|
+
|
|
+# undef SYSCALL_ERROR_LABEL
|
|
+# if RTLD_PRIVATE_ERRNO
|
|
+# define SYSCALL_ERROR_LABEL $syscall_error
|
|
+# define SYSCALL_ERROR_HANDLER \
|
|
+ $syscall_error: \
|
|
+ stw v0, rtld_errno (gp) !gprel; \
|
|
+ ldi v0, -1; \
|
|
+ ret
|
|
+# define SYSCALL_ERROR_FALLTHRU
|
|
+# elif defined(PIC)
|
|
+# define SYSCALL_ERROR_LABEL __syscall_error !samegp
|
|
+# define SYSCALL_ERROR_HANDLER
|
|
+# define SYSCALL_ERROR_FALLTHRU br SYSCALL_ERROR_LABEL
|
|
+# else
|
|
+# define SYSCALL_ERROR_LABEL $syscall_error
|
|
+# define SYSCALL_ERROR_HANDLER \
|
|
+ $syscall_error: \
|
|
+ jmp $31, __syscall_error
|
|
+# define SYSCALL_ERROR_FALLTHRU
|
|
+# endif /* RTLD_PRIVATE_ERRNO */
|
|
+
|
|
+/* Overridden by specific syscalls. */
|
|
+# undef PSEUDO_PREPARE_ARGS
|
|
+# define PSEUDO_PREPARE_ARGS /* Nothing. */
|
|
+
|
|
+# define PSEUDO(name, syscall_name, args) \
|
|
+ .globl name; \
|
|
+ .align 4; \
|
|
+ .ent name, 0; \
|
|
+ __LABEL (name) \
|
|
+ PSEUDO_PROLOGUE; \
|
|
+ PSEUDO_PREPARE_ARGS \
|
|
+ ldi v0, SYS_ify (syscall_name); \
|
|
+ sys_call HMC_callsys; \
|
|
+ bne a3, SYSCALL_ERROR_LABEL
|
|
+
|
|
+# undef PSEUDO_END
|
|
+# define PSEUDO_END(sym) \
|
|
+ SYSCALL_ERROR_HANDLER; \
|
|
+ END (sym)
|
|
+
|
|
+# define PSEUDO_NOERRNO(name, syscall_name, args) \
|
|
+ .globl name; \
|
|
+ .align 4; \
|
|
+ .ent name, 0; \
|
|
+ __LABEL (name) \
|
|
+ PSEUDO_PROLOGUE; \
|
|
+ PSEUDO_PREPARE_ARGS \
|
|
+ ldi v0, SYS_ify (syscall_name); \
|
|
+ sys_call HMC_callsys;
|
|
+
|
|
+# undef PSEUDO_END_NOERRNO
|
|
+# define PSEUDO_END_NOERRNO(sym) END (sym)
|
|
+
|
|
+# define ret_NOERRNO ret
|
|
+
|
|
+# define PSEUDO_ERRVAL(name, syscall_name, args) \
|
|
+ .globl name; \
|
|
+ .align 4; \
|
|
+ .ent name, 0; \
|
|
+ __LABEL (name) \
|
|
+ PSEUDO_PROLOGUE; \
|
|
+ PSEUDO_PREPARE_ARGS \
|
|
+ ldi v0, SYS_ify (syscall_name); \
|
|
+ sys_call HMC_callsys;
|
|
+
|
|
+# undef PSEUDO_END_ERRVAL
|
|
+# define PSEUDO_END_ERRVAL(sym) END (sym)
|
|
+
|
|
+# define ret_ERRVAL ret
|
|
+
|
|
+# define r0 v0
|
|
+# define r1 a4
|
|
+
|
|
+# define MOVE(x, y) mov x, y
|
|
+
|
|
+#else /* !ASSEMBLER */
|
|
+
|
|
+#define HAVE_CLOCK_GETTIME_VSYSCALL "__vdso_clock_gettime"
|
|
+#define HAVE_CLOCK_GETTIME64_VSYSCALL "__vdso_clock_gettime64"
|
|
+
|
|
+#define INTERNAL_SYSCALL(name, nr, args...) \
|
|
+ internal_syscall##nr(__NR_##name, args)
|
|
+
|
|
+# define INTERNAL_SYSCALL_NCS(name, nr, args...) \
|
|
+ internal_syscall##nr (name, args)
|
|
+
|
|
+/* The normal Sw_64 calling convention sign-extends 32-bit quantties
|
|
+ no matter what the "real" sign of the 32-bit type. We want to
|
|
+ preserve that when filling in values for the kernel. */
|
|
+# define syscall_promote(arg) \
|
|
+ (sizeof (arg) == 4 ? (long int) (int) (long int) (arg) : (long int) (arg))
|
|
+
|
|
+# define internal_syscall_clobbers \
|
|
+ "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$22", "$23", "$24", \
|
|
+ "$25", "$27", "$28", "memory"
|
|
+
|
|
+/* It is moderately important optimization-wise to limit the lifetime
|
|
+ of the hard-register variables as much as possible. Thus we copy
|
|
+ in/out as close to the asm as possible. */
|
|
+
|
|
+# define internal_syscall0(name, args...) \
|
|
+ ({ \
|
|
+ register long int _sc_19 __asm__("$19"); \
|
|
+ register long int _sc_0 = name; \
|
|
+ __asm__ __volatile__("sys_call 0x83 # %0 %1 <= %2" \
|
|
+ : "+v"(_sc_0), "=r"(_sc_19) \
|
|
+ : \
|
|
+ : internal_syscall_clobbers, "$16", "$17", "$18", \
|
|
+ "$20", "$21"); \
|
|
+ _sc_19 != 0 ? -_sc_0 : _sc_0; \
|
|
+ })
|
|
+
|
|
+# define internal_syscall1(name, arg1) \
|
|
+ ({ \
|
|
+ register long int _tmp_16 = syscall_promote (arg1); \
|
|
+ register long int _sc_0 = name; \
|
|
+ register long int _sc_16 __asm__("$16") = _tmp_16; \
|
|
+ register long int _sc_19 __asm__("$19"); \
|
|
+ __asm__ __volatile__("sys_call 0x83 # %0 %1 <= %2 %3" \
|
|
+ : "+v"(_sc_0), "=r"(_sc_19), "+r"(_sc_16) \
|
|
+ : \
|
|
+ : internal_syscall_clobbers, "$17", "$18", "$20", \
|
|
+ "$21"); \
|
|
+ _sc_19 != 0 ? -_sc_0 : _sc_0; \
|
|
+ })
|
|
+
|
|
+# define internal_syscall2(name, arg1, arg2) \
|
|
+ ({ \
|
|
+ register long int _tmp_16 = syscall_promote (arg1); \
|
|
+ register long int _tmp_17 = syscall_promote (arg2); \
|
|
+ register long int _sc_0 = name; \
|
|
+ register long int _sc_16 __asm__("$16") = _tmp_16; \
|
|
+ register long int _sc_17 __asm__("$17") = _tmp_17; \
|
|
+ register long int _sc_19 __asm__("$19"); \
|
|
+ __asm__ __volatile__("sys_call 0x83 # %0 %1 <= %2 %3 %4" \
|
|
+ : "+v"(_sc_0), "=r"(_sc_19), "+r"(_sc_16), \
|
|
+ "+r"(_sc_17) \
|
|
+ : \
|
|
+ : internal_syscall_clobbers, "$18", "$20", "$21"); \
|
|
+ _sc_19 != 0 ? -_sc_0 : _sc_0; \
|
|
+ })
|
|
+
|
|
+# define internal_syscall3(name, arg1, arg2, arg3) \
|
|
+ ({ \
|
|
+ register long int _tmp_16 = syscall_promote (arg1); \
|
|
+ register long int _tmp_17 = syscall_promote (arg2); \
|
|
+ register long int _tmp_18 = syscall_promote (arg3); \
|
|
+ register long int _sc_0 = name; \
|
|
+ register long int _sc_16 __asm__("$16") = _tmp_16; \
|
|
+ register long int _sc_17 __asm__("$17") = _tmp_17; \
|
|
+ register long int _sc_18 __asm__("$18") = _tmp_18; \
|
|
+ register long int _sc_19 __asm__("$19"); \
|
|
+ __asm__ __volatile__("sys_call 0x83 # %0 %1 <= %2 %3 %4 %5" \
|
|
+ : "+v"(_sc_0), "=r"(_sc_19), "+r"(_sc_16), \
|
|
+ "+r"(_sc_17), "+r"(_sc_18) \
|
|
+ : \
|
|
+ : internal_syscall_clobbers, "$20", "$21"); \
|
|
+ _sc_19 != 0 ? -_sc_0 : _sc_0; \
|
|
+ })
|
|
+
|
|
+# define internal_syscall4(name, arg1, arg2, arg3, arg4) \
|
|
+ ({ \
|
|
+ register long int _tmp_16 = syscall_promote (arg1); \
|
|
+ register long int _tmp_17 = syscall_promote (arg2); \
|
|
+ register long int _tmp_18 = syscall_promote (arg3); \
|
|
+ register long int _tmp_19 = syscall_promote (arg4); \
|
|
+ register long int _sc_0 = name; \
|
|
+ register long int _sc_16 __asm__("$16") = _tmp_16; \
|
|
+ register long int _sc_17 __asm__("$17") = _tmp_17; \
|
|
+ register long int _sc_18 __asm__("$18") = _tmp_18; \
|
|
+ register long int _sc_19 __asm__("$19") = _tmp_19; \
|
|
+ __asm__ __volatile__("sys_call 0x83 # %0 %1 <= %2 %3 %4 %5 %6" \
|
|
+ : "+v"(_sc_0), "+r"(_sc_19), "+r"(_sc_16), \
|
|
+ "+r"(_sc_17), "+r"(_sc_18) \
|
|
+ : \
|
|
+ : internal_syscall_clobbers, "$20", "$21"); \
|
|
+ _sc_19 != 0 ? -_sc_0 : _sc_0; \
|
|
+ })
|
|
+
|
|
+# define internal_syscall5(name, arg1, arg2, arg3, arg4, arg5) \
|
|
+ ({ \
|
|
+ register long int _tmp_16 = syscall_promote (arg1); \
|
|
+ register long int _tmp_17 = syscall_promote (arg2); \
|
|
+ register long int _tmp_18 = syscall_promote (arg3); \
|
|
+ register long int _tmp_19 = syscall_promote (arg4); \
|
|
+ register long int _tmp_20 = syscall_promote (arg5); \
|
|
+ register long int _sc_0 = name; \
|
|
+ register long int _sc_16 __asm__("$16") = _tmp_16; \
|
|
+ register long int _sc_17 __asm__("$17") = _tmp_17; \
|
|
+ register long int _sc_18 __asm__("$18") = _tmp_18; \
|
|
+ register long int _sc_19 __asm__("$19") = _tmp_19; \
|
|
+ register long int _sc_20 __asm__("$20") = _tmp_20; \
|
|
+ __asm__ __volatile__("sys_call 0x83 # %0 %1 <= %2 %3 %4 %5 %6 %7" \
|
|
+ : "+v"(_sc_0), "+r"(_sc_19), "+r"(_sc_16), \
|
|
+ "+r"(_sc_17), "+r"(_sc_18), "+r"(_sc_20) \
|
|
+ : \
|
|
+ : internal_syscall_clobbers, "$21"); \
|
|
+ _sc_19 != 0 ? -_sc_0 : _sc_0; \
|
|
+ })
|
|
+
|
|
+# define internal_syscall6(name, arg1, arg2, arg3, arg4, arg5, arg6) \
|
|
+ ({ \
|
|
+ register long int _tmp_16 = syscall_promote (arg1); \
|
|
+ register long int _tmp_17 = syscall_promote (arg2); \
|
|
+ register long int _tmp_18 = syscall_promote (arg3); \
|
|
+ register long int _tmp_19 = syscall_promote (arg4); \
|
|
+ register long int _tmp_20 = syscall_promote (arg5); \
|
|
+ register long int _tmp_21 = syscall_promote (arg6); \
|
|
+ register long int _sc_0 = name; \
|
|
+ register long int _sc_16 __asm__("$16") = _tmp_16; \
|
|
+ register long int _sc_17 __asm__("$17") = _tmp_17; \
|
|
+ register long int _sc_18 __asm__("$18") = _tmp_18; \
|
|
+ register long int _sc_19 __asm__("$19") = _tmp_19; \
|
|
+ register long int _sc_20 __asm__("$20") = _tmp_20; \
|
|
+ register long int _sc_21 __asm__("$21") = _tmp_21; \
|
|
+ __asm__ __volatile__("sys_call 0x83 # %0 %1 <= %2 %3 %4 %5 %6 %7 %8" \
|
|
+ : "+v"(_sc_0), "+r"(_sc_19), "+r"(_sc_16), \
|
|
+ "+r"(_sc_17), "+r"(_sc_18), "+r"(_sc_20), \
|
|
+ "+r"(_sc_21) \
|
|
+ : \
|
|
+ : internal_syscall_clobbers); \
|
|
+ _sc_19 != 0 ? -_sc_0 : _sc_0; \
|
|
+ })
|
|
+#endif /* ASSEMBLER */
|
|
+
|
|
+/* Pointer mangling support. Note that tls access is slow enough that
|
|
+ we don't deoptimize things by placing the pointer check value there. */
|
|
+
|
|
+#ifdef __ASSEMBLER__
|
|
+# if IS_IN(rtld)
|
|
+# define PTR_MANGLE(dst, src, tmp) \
|
|
+ ldih tmp, __pointer_chk_guard_local ($29) !gprelhigh; \
|
|
+ ldl tmp, __pointer_chk_guard_local (tmp) !gprellow; \
|
|
+ xor src, tmp, dst
|
|
+# define PTR_MANGLE2(dst, src, tmp) xor src, tmp, dst
|
|
+# elif defined SHARED
|
|
+# define PTR_MANGLE(dst, src, tmp) \
|
|
+ ldl tmp, __pointer_chk_guard; \
|
|
+ xor src, tmp, dst
|
|
+# else
|
|
+# define PTR_MANGLE(dst, src, tmp) \
|
|
+ ldl tmp, __pointer_chk_guard_local; \
|
|
+ xor src, tmp, dst
|
|
+# endif
|
|
+# define PTR_MANGLE2(dst, src, tmp) xor src, tmp, dst
|
|
+# define PTR_DEMANGLE(dst, tmp) PTR_MANGLE (dst, dst, tmp)
|
|
+# define PTR_DEMANGLE2(dst, tmp) PTR_MANGLE2 (dst, dst, tmp)
|
|
+#else
|
|
+# include <stdint.h>
|
|
+# if (IS_IN(rtld) || (!defined SHARED && (IS_IN(libc) || IS_IN(libpthread))))
|
|
+extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
|
|
+# define PTR_MANGLE(var) \
|
|
+ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local)
|
|
+# else
|
|
+extern uintptr_t __pointer_chk_guard attribute_relro;
|
|
+# define PTR_MANGLE(var) \
|
|
+ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard)
|
|
+# endif
|
|
+# define PTR_DEMANGLE(var) PTR_MANGLE (var)
|
|
+#endif /* ASSEMBLER */
|
|
+
|
|
+#endif /* _LINUX_SW_64_SYSDEP_H */
|
|
diff --git a/sysdeps/unix/sysv/linux/sw_64/vfork.S b/sysdeps/unix/sysv/linux/sw_64/vfork.S
|
|
new file mode 100644
|
|
index 00000000..a79eb93a
|
|
--- /dev/null
|
|
+++ b/sysdeps/unix/sysv/linux/sw_64/vfork.S
|
|
@@ -0,0 +1,41 @@
|
|
+/* Copyright (C) 2004-2023 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library. If not, see
|
|
+ <http://www.gnu.org/licenses/>. */
|
|
+
|
|
+#include <sysdep.h>
|
|
+#include <tcb-offsets.h>
|
|
+
|
|
+ENTRY(__libc_vfork)
|
|
+ PSEUDO_PROLOGUE
|
|
+
|
|
+ /* Load the thread pointer value in A1 across the vfork. */
|
|
+ sys_call 0x9e
|
|
+ mov v0, a1
|
|
+
|
|
+ ldi v0, SYS_ify(vfork)
|
|
+ sys_call HMC_callsys
|
|
+
|
|
+ /* Normal error check and return. */
|
|
+ bne a3, SYSCALL_ERROR_LABEL
|
|
+ ret
|
|
+
|
|
+PSEUDO_END (__libc_vfork)
|
|
+
|
|
+#if IS_IN (libc)
|
|
+weak_alias (__libc_vfork, vfork)
|
|
+strong_alias (__libc_vfork, __vfork)
|
|
+libc_hidden_def (__vfork)
|
|
+#endif
|
|
--
|
|
2.25.1
|
|
|