user: implement mlibc as the libc, finally.

It's finally done..

Signed-off-by: kaguya <vpshinomiya@protonmail.com>
This commit is contained in:
kaguya
2026-05-02 03:31:49 -04:00
parent 2fa39ad85a
commit 9a9b91c940
2387 changed files with 152741 additions and 315 deletions
@@ -0,0 +1,117 @@
#include <sys/syscall.h>
#include <bits/syscall.h>
using sc_word_t = __sc_word_t;
sc_word_t __do_syscall0(long sc) {
register int sc_reg asm("x8") = sc;
register sc_word_t ret asm("x0");
asm volatile ("svc 0" : "=r"(ret) : "r"(sc_reg) : "memory");
return ret;
}
sc_word_t __do_syscall1(long sc,
sc_word_t arg1) {
register int sc_reg asm("x8") = sc;
register sc_word_t arg1_reg asm("x0") = arg1;
register sc_word_t ret asm("x0");
asm volatile ("svc 0" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg)
: "memory");
return ret;
}
sc_word_t __do_syscall2(long sc,
sc_word_t arg1, sc_word_t arg2) {
register int sc_reg asm("x8") = sc;
register sc_word_t arg1_reg asm("x0") = arg1;
register sc_word_t arg2_reg asm("x1") = arg2;
register sc_word_t ret asm("x0");
asm volatile ("svc 0" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg),
"r"(arg2_reg)
: "memory");
return ret;
}
sc_word_t __do_syscall3(long sc,
sc_word_t arg1, sc_word_t arg2, sc_word_t arg3) {
register int sc_reg asm("x8") = sc;
register sc_word_t arg1_reg asm("x0") = arg1;
register sc_word_t arg2_reg asm("x1") = arg2;
register sc_word_t arg3_reg asm("x2") = arg3;
register sc_word_t ret asm("x0");
asm volatile ("svc 0" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg),
"r"(arg2_reg),
"r"(arg3_reg)
: "memory");
return ret;
}
sc_word_t __do_syscall4(long sc,
sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4) {
register int sc_reg asm("x8") = sc;
register sc_word_t arg1_reg asm("x0") = arg1;
register sc_word_t arg2_reg asm("x1") = arg2;
register sc_word_t arg3_reg asm("x2") = arg3;
register sc_word_t arg4_reg asm("x3") = arg4;
register sc_word_t ret asm("x0");
asm volatile ("svc 0" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg),
"r"(arg2_reg),
"r"(arg3_reg),
"r"(arg4_reg)
: "memory");
return ret;
}
sc_word_t __do_syscall5(long sc,
sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4, sc_word_t arg5) {
register int sc_reg asm("x8") = sc;
register sc_word_t arg1_reg asm("x0") = arg1;
register sc_word_t arg2_reg asm("x1") = arg2;
register sc_word_t arg3_reg asm("x2") = arg3;
register sc_word_t arg4_reg asm("x3") = arg4;
register sc_word_t arg5_reg asm("x4") = arg5;
register sc_word_t ret asm("x0");
asm volatile ("svc 0" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg),
"r"(arg2_reg),
"r"(arg3_reg),
"r"(arg4_reg),
"r"(arg5_reg)
: "memory");
return ret;
}
sc_word_t __do_syscall6(long sc,
sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4, sc_word_t arg5, sc_word_t arg6) {
register int sc_reg asm("x8") = sc;
register sc_word_t arg1_reg asm("x0") = arg1;
register sc_word_t arg2_reg asm("x1") = arg2;
register sc_word_t arg3_reg asm("x2") = arg3;
register sc_word_t arg4_reg asm("x3") = arg4;
register sc_word_t arg5_reg asm("x4") = arg5;
register sc_word_t arg6_reg asm("x5") = arg6;
register sc_word_t ret asm("x0");
asm volatile ("svc 0" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg),
"r"(arg2_reg),
"r"(arg3_reg),
"r"(arg4_reg),
"r"(arg5_reg),
"r"(arg6_reg)
: "memory"
);
return ret;
}
@@ -0,0 +1,31 @@
.section .text
.global __mlibc_do_asm_cp_syscall
.global __mlibc_syscall_begin
.global __mlibc_syscall_end
.type __mlibc_do_asm_cp_syscall, "function"
__mlibc_do_asm_cp_syscall:
mov x8, x0
mov x0, x1
mov x1, x2
mov x2, x3
mov x3, x4
mov x4, x5
mov x5, x6
mrs x7, tpidr_el0
ldr w7, [x7, #-80] // Tcb::cancelBits. See asserts in tcb.hpp.
__mlibc_syscall_begin:
// tcbCancelEnableBit && tcbCancelTriggerBit
mov x9, #((1 << 0) | (1 << 2))
and x7, x7, x9
cmp x7, x9
b.eq cancel
svc 0
__mlibc_syscall_end:
ret
cancel:
bl __mlibc_do_cancel
brk #0
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,11 @@
.section .text
.global _start
_start:
mov x0, sp
adr x1, main
bl __mlibc_entry
brk #0
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,9 @@
.section .text
.global _start
_start:
mov x0, sp
adrp x1, main
add x1, x1, :lo12:main
bl __mlibc_entry
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,13 @@
.section .init
.global _init
_init:
stp x29, x30, [sp, -16]!
mov x29, sp
.section .fini
.global _fini
_fini:
stp x29, x30, [sp, -16]!
mov x29, sp
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,9 @@
.section .init
ldp x29, x30, [sp], #16
ret
.section .fini
ldp x29, x30, [sp], #16
ret
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,12 @@
.section .text
.global __mlibc_signal_restore
.type __mlibc_signal_restore, @function
__mlibc_signal_restore:
.global __mlibc_signal_restore_rt
.type __mlibc_signal_restore_rt, @function
__mlibc_signal_restore_rt:
mov x8,#139 // SYS_rt_sigreturn
svc 0
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,327 @@
#ifndef __MLIBC_SYSCALLNOS_h
#define __MLIBC_SYSCALLNOS_h
/* This file is autogenerated. Don't bother. */
/* Generator script: sysdeps/linux/update-syscall-list.py. */
#define __NR_io_setup 0
#define __NR_io_destroy 1
#define __NR_io_submit 2
#define __NR_io_cancel 3
#define __NR_io_getevents 4
#define __NR_setxattr 5
#define __NR_lsetxattr 6
#define __NR_fsetxattr 7
#define __NR_getxattr 8
#define __NR_lgetxattr 9
#define __NR_fgetxattr 10
#define __NR_listxattr 11
#define __NR_llistxattr 12
#define __NR_flistxattr 13
#define __NR_removexattr 14
#define __NR_lremovexattr 15
#define __NR_fremovexattr 16
#define __NR_getcwd 17
#define __NR_lookup_dcookie 18
#define __NR_eventfd2 19
#define __NR_epoll_create1 20
#define __NR_epoll_ctl 21
#define __NR_epoll_pwait 22
#define __NR_dup 23
#define __NR_dup3 24
#define __NR_fcntl 25
#define __NR_inotify_init1 26
#define __NR_inotify_add_watch 27
#define __NR_inotify_rm_watch 28
#define __NR_ioctl 29
#define __NR_ioprio_set 30
#define __NR_ioprio_get 31
#define __NR_flock 32
#define __NR_mknodat 33
#define __NR_mkdirat 34
#define __NR_unlinkat 35
#define __NR_symlinkat 36
#define __NR_linkat 37
#define __NR_renameat 38
#define __NR_umount2 39
#define __NR_mount 40
#define __NR_pivot_root 41
#define __NR_nfsservctl 42
#define __NR_statfs 43
#define __NR_fstatfs 44
#define __NR_truncate 45
#define __NR_ftruncate 46
#define __NR_fallocate 47
#define __NR_faccessat 48
#define __NR_chdir 49
#define __NR_fchdir 50
#define __NR_chroot 51
#define __NR_fchmod 52
#define __NR_fchmodat 53
#define __NR_fchownat 54
#define __NR_fchown 55
#define __NR_openat 56
#define __NR_close 57
#define __NR_vhangup 58
#define __NR_pipe2 59
#define __NR_quotactl 60
#define __NR_getdents64 61
#define __NR_lseek 62
#define __NR_read 63
#define __NR_write 64
#define __NR_readv 65
#define __NR_writev 66
#define __NR_pread64 67
#define __NR_pwrite64 68
#define __NR_preadv 69
#define __NR_pwritev 70
#define __NR_sendfile 71
#define __NR_pselect6 72
#define __NR_ppoll 73
#define __NR_signalfd4 74
#define __NR_vmsplice 75
#define __NR_splice 76
#define __NR_tee 77
#define __NR_readlinkat 78
#define __NR_newfstatat 79
#define __NR_fstat 80
#define __NR_sync 81
#define __NR_fsync 82
#define __NR_fdatasync 83
#define __NR_sync_file_range 84
#define __NR_timerfd_create 85
#define __NR_timerfd_settime 86
#define __NR_timerfd_gettime 87
#define __NR_utimensat 88
#define __NR_acct 89
#define __NR_capget 90
#define __NR_capset 91
#define __NR_personality 92
#define __NR_exit 93
#define __NR_exit_group 94
#define __NR_waitid 95
#define __NR_set_tid_address 96
#define __NR_unshare 97
#define __NR_futex 98
#define __NR_set_robust_list 99
#define __NR_get_robust_list 100
#define __NR_nanosleep 101
#define __NR_getitimer 102
#define __NR_setitimer 103
#define __NR_kexec_load 104
#define __NR_init_module 105
#define __NR_delete_module 106
#define __NR_timer_create 107
#define __NR_timer_gettime 108
#define __NR_timer_getoverrun 109
#define __NR_timer_settime 110
#define __NR_timer_delete 111
#define __NR_clock_settime 112
#define __NR_clock_gettime 113
#define __NR_clock_getres 114
#define __NR_clock_nanosleep 115
#define __NR_syslog 116
#define __NR_ptrace 117
#define __NR_sched_setparam 118
#define __NR_sched_setscheduler 119
#define __NR_sched_getscheduler 120
#define __NR_sched_getparam 121
#define __NR_sched_setaffinity 122
#define __NR_sched_getaffinity 123
#define __NR_sched_yield 124
#define __NR_sched_get_priority_max 125
#define __NR_sched_get_priority_min 126
#define __NR_sched_rr_get_interval 127
#define __NR_restart_syscall 128
#define __NR_kill 129
#define __NR_tkill 130
#define __NR_tgkill 131
#define __NR_sigaltstack 132
#define __NR_rt_sigsuspend 133
#define __NR_rt_sigaction 134
#define __NR_rt_sigprocmask 135
#define __NR_rt_sigpending 136
#define __NR_rt_sigtimedwait 137
#define __NR_rt_sigqueueinfo 138
#define __NR_rt_sigreturn 139
#define __NR_setpriority 140
#define __NR_getpriority 141
#define __NR_reboot 142
#define __NR_setregid 143
#define __NR_setgid 144
#define __NR_setreuid 145
#define __NR_setuid 146
#define __NR_setresuid 147
#define __NR_getresuid 148
#define __NR_setresgid 149
#define __NR_getresgid 150
#define __NR_setfsuid 151
#define __NR_setfsgid 152
#define __NR_times 153
#define __NR_setpgid 154
#define __NR_getpgid 155
#define __NR_getsid 156
#define __NR_setsid 157
#define __NR_getgroups 158
#define __NR_setgroups 159
#define __NR_uname 160
#define __NR_sethostname 161
#define __NR_setdomainname 162
#define __NR_getrlimit 163
#define __NR_setrlimit 164
#define __NR_getrusage 165
#define __NR_umask 166
#define __NR_prctl 167
#define __NR_getcpu 168
#define __NR_gettimeofday 169
#define __NR_settimeofday 170
#define __NR_adjtimex 171
#define __NR_getpid 172
#define __NR_getppid 173
#define __NR_getuid 174
#define __NR_geteuid 175
#define __NR_getgid 176
#define __NR_getegid 177
#define __NR_gettid 178
#define __NR_sysinfo 179
#define __NR_mq_open 180
#define __NR_mq_unlink 181
#define __NR_mq_timedsend 182
#define __NR_mq_timedreceive 183
#define __NR_mq_notify 184
#define __NR_mq_getsetattr 185
#define __NR_msgget 186
#define __NR_msgctl 187
#define __NR_msgrcv 188
#define __NR_msgsnd 189
#define __NR_semget 190
#define __NR_semctl 191
#define __NR_semtimedop 192
#define __NR_semop 193
#define __NR_shmget 194
#define __NR_shmctl 195
#define __NR_shmat 196
#define __NR_shmdt 197
#define __NR_socket 198
#define __NR_socketpair 199
#define __NR_bind 200
#define __NR_listen 201
#define __NR_accept 202
#define __NR_connect 203
#define __NR_getsockname 204
#define __NR_getpeername 205
#define __NR_sendto 206
#define __NR_recvfrom 207
#define __NR_setsockopt 208
#define __NR_getsockopt 209
#define __NR_shutdown 210
#define __NR_sendmsg 211
#define __NR_recvmsg 212
#define __NR_readahead 213
#define __NR_brk 214
#define __NR_munmap 215
#define __NR_mremap 216
#define __NR_add_key 217
#define __NR_request_key 218
#define __NR_keyctl 219
#define __NR_clone 220
#define __NR_execve 221
#define __NR_mmap 222
#define __NR_fadvise64 223
#define __NR_swapon 224
#define __NR_swapoff 225
#define __NR_mprotect 226
#define __NR_msync 227
#define __NR_mlock 228
#define __NR_munlock 229
#define __NR_mlockall 230
#define __NR_munlockall 231
#define __NR_mincore 232
#define __NR_madvise 233
#define __NR_remap_file_pages 234
#define __NR_mbind 235
#define __NR_get_mempolicy 236
#define __NR_set_mempolicy 237
#define __NR_migrate_pages 238
#define __NR_move_pages 239
#define __NR_rt_tgsigqueueinfo 240
#define __NR_perf_event_open 241
#define __NR_accept4 242
#define __NR_recvmmsg 243
#define __NR_wait4 260
#define __NR_prlimit64 261
#define __NR_fanotify_init 262
#define __NR_fanotify_mark 263
#define __NR_name_to_handle_at 264
#define __NR_open_by_handle_at 265
#define __NR_clock_adjtime 266
#define __NR_syncfs 267
#define __NR_setns 268
#define __NR_sendmmsg 269
#define __NR_process_vm_readv 270
#define __NR_process_vm_writev 271
#define __NR_kcmp 272
#define __NR_finit_module 273
#define __NR_sched_setattr 274
#define __NR_sched_getattr 275
#define __NR_renameat2 276
#define __NR_seccomp 277
#define __NR_getrandom 278
#define __NR_memfd_create 279
#define __NR_bpf 280
#define __NR_execveat 281
#define __NR_userfaultfd 282
#define __NR_membarrier 283
#define __NR_mlock2 284
#define __NR_copy_file_range 285
#define __NR_preadv2 286
#define __NR_pwritev2 287
#define __NR_pkey_mprotect 288
#define __NR_pkey_alloc 289
#define __NR_pkey_free 290
#define __NR_statx 291
#define __NR_io_pgetevents 292
#define __NR_rseq 293
#define __NR_kexec_file_load 294
#define __NR_pidfd_send_signal 424
#define __NR_io_uring_setup 425
#define __NR_io_uring_enter 426
#define __NR_io_uring_register 427
#define __NR_open_tree 428
#define __NR_move_mount 429
#define __NR_fsopen 430
#define __NR_fsconfig 431
#define __NR_fsmount 432
#define __NR_fspick 433
#define __NR_pidfd_open 434
#define __NR_clone3 435
#define __NR_close_range 436
#define __NR_openat2 437
#define __NR_pidfd_getfd 438
#define __NR_faccessat2 439
#define __NR_process_madvise 440
#define __NR_epoll_pwait2 441
#define __NR_mount_setattr 442
#define __NR_quotactl_fd 443
#define __NR_landlock_create_ruleset 444
#define __NR_landlock_add_rule 445
#define __NR_landlock_restrict_self 446
#define __NR_memfd_secret 447
#define __NR_process_mrelease 448
#define __NR_futex_waitv 449
#define __NR_set_mempolicy_home_node 450
#define __NR_cachestat 451
#define __NR_fchmodat2 452
#define __NR_map_shadow_stack 453
#define __NR_futex_wake 454
#define __NR_futex_wait 455
#define __NR_futex_requeue 456
#define __NR_statmount 457
#define __NR_listmount 458
#define __NR_lsm_get_self_attr 459
#define __NR_lsm_set_self_attr 460
#define __NR_lsm_list_modules 461
#define __NR_mseal 462
#define __NR_setxattrat 463
#define __NR_getxattrat 464
#define __NR_listxattrat 465
#define __NR_removexattrat 466
#endif /* __MLIBC_SYSCALLNOS_h */
@@ -0,0 +1,27 @@
.section .text
.global __mlibc_spawn_thread
.type __mlibc_spawn_thread, "function"
__mlibc_spawn_thread:
// __mlibc_spawn_thread(flags, stack, pid_out, child_tid, tls)
// x0, x1, x2, x3, x4
// syscall(NR_clone, flags, stack, ptid, tls, ctid)
// x8, x0, x1, x2, x3, x4
// Swap x3 <-> x4
mov x5, x4
mov x4, x3
mov x3, x5
mov x8, 220 // NR_clone
svc 0
cbnz x0, .parent
ldp x0, x1, [sp], #16
bl __mlibc_enter_thread
brk #0
.parent:
ret
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,118 @@
#pragma once
#include <errno.h>
#include <mlibc/tcb.hpp>
#include <mlibc/thread.hpp>
#include <mlibc-config.h>
#include <utility>
#include <sys/syscall.h>
#include <bits/syscall.h>
using sc_word_t = __sc_word_t;
extern "C" {
extern sc_word_t __mlibc_do_asm_cp_syscall(int sc, sc_word_t arg1, sc_word_t arg2,
sc_word_t arg3, sc_word_t arg4, sc_word_t arg5, sc_word_t arg6);
extern void __mlibc_do_cancel();
}
namespace mlibc {
// C++ wrappers for the extern "C" functions.
inline sc_word_t do_nargs_syscall(int sc) {
return __do_syscall0(sc);
}
inline sc_word_t do_nargs_syscall(int sc, sc_word_t arg1) {
return __do_syscall1(sc, arg1);
}
inline sc_word_t do_nargs_syscall(int sc, sc_word_t arg1, sc_word_t arg2) {
return __do_syscall2(sc, arg1, arg2);
}
inline sc_word_t do_nargs_syscall(int sc, sc_word_t arg1, sc_word_t arg2, sc_word_t arg3) {
return __do_syscall3(sc, arg1, arg2, arg3);
}
inline sc_word_t do_nargs_syscall(int sc, sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4) {
return __do_syscall4(sc, arg1, arg2, arg3, arg4);
}
inline sc_word_t do_nargs_syscall(int sc, sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4, sc_word_t arg5) {
return __do_syscall5(sc, arg1, arg2, arg3, arg4, arg5);
}
inline sc_word_t do_nargs_syscall(int sc, sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4, sc_word_t arg5, sc_word_t arg6) {
return __do_syscall6(sc, arg1, arg2, arg3, arg4, arg5, arg6);
}
inline sc_word_t do_nargs_cp_syscall(int sc, sc_word_t arg1) {
return __mlibc_do_asm_cp_syscall(sc, arg1, 0, 0, 0, 0, 0);
}
inline sc_word_t do_nargs_cp_syscall(int sc, sc_word_t arg1, sc_word_t arg2) {
return __mlibc_do_asm_cp_syscall(sc, arg1, arg2, 0, 0, 0, 0);
}
inline sc_word_t do_nargs_cp_syscall(int sc, sc_word_t arg1, sc_word_t arg2,
sc_word_t arg3) {
return __mlibc_do_asm_cp_syscall(sc, arg1, arg2, arg3, 0, 0, 0);
}
inline sc_word_t do_nargs_cp_syscall(int sc, sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4) {
return __mlibc_do_asm_cp_syscall(sc, arg1, arg2, arg3, arg4, 0, 0);
}
inline sc_word_t do_nargs_cp_syscall(int sc, sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4, sc_word_t arg5) {
return __mlibc_do_asm_cp_syscall(sc, arg1, arg2, arg3, arg4, arg5, 0);
}
inline sc_word_t do_nargs_cp_syscall(int sc, sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4, sc_word_t arg5, sc_word_t arg6) {
return __mlibc_do_asm_cp_syscall(sc, arg1, arg2, arg3, arg4, arg5, arg6);
}
// Type-safe syscall result type.
enum class sc_result_t : sc_word_t { };
// Cast to the argument type of the extern "C" functions.
inline sc_word_t sc_cast(long x) { return x; }
inline sc_word_t sc_cast(const void *x) { return reinterpret_cast<sc_word_t>(x); }
template<typename... T>
sc_result_t do_syscall(int sc, T... args) {
return static_cast<sc_result_t>(do_nargs_syscall(sc, sc_cast(args)...));
}
inline int sc_error(sc_result_t ret) {
auto v = static_cast<sc_word_t>(ret);
if(static_cast<unsigned long>(v) > -4096UL)
return -v;
return 0;
}
template<typename... T>
sc_result_t do_cp_syscall(int sc, T... args) {
#if __MLIBC_POSIX_OPTION && !MLIBC_BUILDING_RTLD
auto result = static_cast<sc_result_t>(do_nargs_cp_syscall(sc, sc_cast(args)...));
if (int e = sc_error(result); e) {
auto tcb = reinterpret_cast<Tcb*>(get_current_tcb());
if (tcb_cancelled(tcb->cancelBits) && e == EINTR) {
__mlibc_do_cancel();
__builtin_unreachable();
}
}
return result;
#else
return do_syscall(sc, std::forward<T>(args)...);
#endif // __MLIBC_POSIX_OPTION || !MLIBC_BUILDING_RTLD
}
// Cast from the syscall result type.
template<typename T>
T sc_int_result(sc_result_t ret) {
auto v = static_cast<sc_word_t>(ret);
return v;
}
template<typename T>
T *sc_ptr_result(sc_result_t ret) {
auto v = static_cast<sc_word_t>(ret);
return reinterpret_cast<T *>(v);
}
}
@@ -0,0 +1,18 @@
#include <stdint.h>
#include <stdlib.h>
#include <bits/ensure.h>
#include <mlibc/elf/startup.h>
#include <sys/auxv.h>
extern "C" void __dlapi_enter(uintptr_t *);
extern char **environ;
size_t __hwcap;
extern "C" void __mlibc_entry(uintptr_t *entry_stack, int (*main_fn)(int argc, char *argv[], char *env[])) {
__dlapi_enter(entry_stack);
__hwcap = getauxval(AT_HWCAP);
auto result = main_fn(mlibc::entry_stack.argc, mlibc::entry_stack.argv, environ);
exit(result);
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,60 @@
#include <mlibc/thread-entry.hpp>
#include <mlibc/all-sysdeps.hpp>
#include <mlibc/thread.hpp>
#include <bits/ensure.h>
#include <sys/mman.h>
#include <stdint.h>
#include <stddef.h>
#include <errno.h>
extern "C" void __mlibc_enter_thread(void *entry, void *user_arg) {
// The linux kernel already sets the TCB in sys_clone().
auto tcb = mlibc::get_current_tcb();
// Wait until our parent sets up the TID.
while(!__atomic_load_n(&tcb->tid, __ATOMIC_RELAXED))
mlibc::sys_futex_wait(&tcb->tid, 0, nullptr);
tcb->invokeThreadFunc(entry, user_arg);
__atomic_store_n(&tcb->didExit, 1, __ATOMIC_RELEASE);
mlibc::sys_futex_wake(&tcb->didExit);
mlibc::sys_thread_exit();
}
namespace mlibc {
static constexpr size_t default_stacksize = 0x200000;
int sys_prepare_stack(void **stack, void *entry, void *user_arg, void *tcb, size_t *stack_size, size_t *guard_size, void **stack_base) {
(void)tcb;
if (!*stack_size)
*stack_size = default_stacksize;
uintptr_t map;
if (*stack) {
map = reinterpret_cast<uintptr_t>(*stack);
*guard_size = 0;
} else {
map = reinterpret_cast<uintptr_t>(
mmap(nullptr, *stack_size + *guard_size,
PROT_NONE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)
);
if (reinterpret_cast<void*>(map) == MAP_FAILED)
return EAGAIN;
int ret = mprotect(reinterpret_cast<void*>(map + *guard_size), *stack_size,
PROT_READ | PROT_WRITE);
if(ret)
return EAGAIN;
}
*stack_base = reinterpret_cast<void*>(map);
auto sp = reinterpret_cast<uintptr_t*>(map + *guard_size + *stack_size);
*--sp = reinterpret_cast<uintptr_t>(user_arg);
*--sp = reinterpret_cast<uintptr_t>(entry);
*stack = reinterpret_cast<void*>(sp);
return 0;
}
} // namespace mlibc
@@ -0,0 +1,2 @@
/* stub header not present in practice, redirects to our internal syscallnos */
#include <syscallnos.h>
@@ -0,0 +1 @@
../../../../abis/linux/access.h
+1
View File
@@ -0,0 +1 @@
../../../../abis/linux/auxv.h
@@ -0,0 +1 @@
../../../../abis/linux/blkcnt_t.h
@@ -0,0 +1 @@
../../../../abis/linux/blksize_t.h
@@ -0,0 +1 @@
../../../../abis/linux/clockid_t.h
@@ -0,0 +1 @@
../../../../abis/linux/dev_t.h
@@ -0,0 +1 @@
../../../../abis/linux/epoll.h
@@ -0,0 +1 @@
../../../../abis/linux/errno.h
@@ -0,0 +1 @@
../../../../abis/linux/fcntl.h
@@ -0,0 +1 @@
../../../../abis/linux/fsblkcnt_t.h
@@ -0,0 +1 @@
../../../../abis/linux/fsfilcnt_t.h
@@ -0,0 +1 @@
../../../../abis/linux/gid_t.h
+1
View File
@@ -0,0 +1 @@
../../../../abis/linux/in.h
@@ -0,0 +1 @@
../../../../abis/linux/ino_t.h
@@ -0,0 +1 @@
../../../../abis/linux/inotify.h
@@ -0,0 +1 @@
../../../../abis/linux/ioctls.h
+1
View File
@@ -0,0 +1 @@
../../../../abis/linux/ipc.h
@@ -0,0 +1 @@
../../../../abis/linux/limits.h
@@ -0,0 +1 @@
../../../../abis/linux/mode_t.h
@@ -0,0 +1 @@
../../../../abis/linux/mqueue.h
+1
View File
@@ -0,0 +1 @@
../../../../abis/linux/msg.h
@@ -0,0 +1 @@
../../../../abis/linux/nlink_t.h
@@ -0,0 +1 @@
../../../../abis/linux/packet.h
@@ -0,0 +1 @@
../../../../abis/linux/pid_t.h
+1
View File
@@ -0,0 +1 @@
../../../../abis/linux/poll.h
@@ -0,0 +1 @@
../../../../abis/linux/ptrace.h
@@ -0,0 +1 @@
../../../../abis/linux/random.h
@@ -0,0 +1 @@
../../../../abis/linux/reboot.h
@@ -0,0 +1 @@
../../../../abis/linux/resource.h
@@ -0,0 +1 @@
../../../../abis/linux/riscv-hwprobe.h
@@ -0,0 +1 @@
../../../../abis/linux/rlim_t.h
@@ -0,0 +1 @@
../../../../abis/linux/seek-whence.h
+1
View File
@@ -0,0 +1 @@
../../../../abis/linux/shm.h
@@ -0,0 +1 @@
../../../../abis/linux/sigevent.h
@@ -0,0 +1 @@
../../../../abis/linux/signal.h
@@ -0,0 +1 @@
../../../../abis/linux/sigval.h
@@ -0,0 +1 @@
../../../../abis/linux/socket.h
@@ -0,0 +1 @@
../../../../abis/linux/socklen_t.h
+1
View File
@@ -0,0 +1 @@
../../../../abis/linux/stat.h
@@ -0,0 +1 @@
../../../../abis/linux/statfs.h
@@ -0,0 +1 @@
../../../../abis/linux/statvfs.h
@@ -0,0 +1 @@
../../../../abis/linux/statx.h
@@ -0,0 +1 @@
../../../../abis/linux/suseconds_t.h
@@ -0,0 +1 @@
../../../../abis/linux/termios.h
+1
View File
@@ -0,0 +1 @@
../../../../abis/linux/time.h
@@ -0,0 +1 @@
../../../../abis/linux/uid_t.h
@@ -0,0 +1 @@
../../../../abis/linux/utmp-defines.h
@@ -0,0 +1 @@
../../../../abis/linux/utmpx.h
@@ -0,0 +1 @@
../../../../abis/linux/utsname.h
@@ -0,0 +1 @@
../../../../abis/linux/vm-flags.h
+1
View File
@@ -0,0 +1 @@
../../../../abis/linux/vt.h
+1
View File
@@ -0,0 +1 @@
../../../../abis/linux/wait.h
@@ -0,0 +1 @@
../../../../abis/linux/xattr.h
@@ -0,0 +1,100 @@
#ifndef _MLIBC_SYSCALL_H
#define _MLIBC_SYSCALL_H
#ifdef __cplusplus
extern "C" {
#endif
typedef long __sc_word_t;
/* These functions are implemented in arch-syscall.cpp. */
__sc_word_t __do_syscall0(long);
__sc_word_t __do_syscall1(long, __sc_word_t);
__sc_word_t __do_syscall2(long, __sc_word_t, __sc_word_t);
__sc_word_t __do_syscall3(long, __sc_word_t, __sc_word_t, __sc_word_t);
__sc_word_t __do_syscall4(long, __sc_word_t, __sc_word_t, __sc_word_t, __sc_word_t);
__sc_word_t __do_syscall5(long, __sc_word_t, __sc_word_t, __sc_word_t, __sc_word_t,
__sc_word_t);
__sc_word_t __do_syscall6(long, __sc_word_t, __sc_word_t, __sc_word_t, __sc_word_t,
__sc_word_t, __sc_word_t);
__sc_word_t __do_syscall7(long, __sc_word_t, __sc_word_t, __sc_word_t, __sc_word_t,
__sc_word_t, __sc_word_t, __sc_word_t);
long __do_syscall_ret(unsigned long);
#ifdef __cplusplus
extern "C++" {
/* Defining a syscall as a macro is more problematic in C++, since there's a high chance of
* a name collision e.g foo.syscall() or foo::syscall.
*/
inline long syscall(long n) {
return __do_syscall_ret(__do_syscall0(n));
}
template<typename Arg0>
long syscall(long n, Arg0 a0) {
return __do_syscall_ret(__do_syscall1(n, (long)a0));
}
template<typename Arg0, typename Arg1>
long syscall(long n, Arg0 a0, Arg1 a1) {
return __do_syscall_ret(__do_syscall2(n, (long)a0, (long)a1));
}
template<typename Arg0, typename Arg1, typename Arg2>
long syscall(long n, Arg0 a0, Arg1 a1, Arg2 a2) {
return __do_syscall_ret(__do_syscall3(n, (long)a0, (long)a1, (long)a2));
}
template<typename Arg0, typename Arg1, typename Arg2, typename Arg3>
long syscall(long n, Arg0 a0, Arg1 a1, Arg2 a2, Arg3 a3) {
return __do_syscall_ret(__do_syscall4(n, (long)a0, (long)a1, (long)a2, (long)a3));
}
template<typename Arg0, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
long syscall(long n, Arg0 a0, Arg1 a1, Arg2 a2, Arg3 a3, Arg4 a4) {
return __do_syscall_ret(__do_syscall5(n, (long)a0, (long)a1, (long)a2, (long)a3, (long)a4));
}
template<typename Arg0, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
long syscall(long n, Arg0 a0, Arg1 a1, Arg2 a2, Arg3 a3, Arg4 a4, Arg5 a5) {
return __do_syscall_ret(__do_syscall6(n, (long)a0, (long)a1, (long)a2, (long)a3, (long)a4, (long)a5));
}
template<typename Arg0, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6>
long syscall(long n, Arg0 a0, Arg1 a1, Arg2 a2, Arg3 a3, Arg4 a4, Arg5 a5, Arg6 a6) {
return __do_syscall_ret(__do_syscall7(n, (long)a0, (long)a1, (long)a2, (long)a3, (long)a4, (long)a5, (long)a6));
}
} /* extern C++ */
#else
/*
* Variadic macros are not supported in C89.
* glibc implements syscall() as a variadic function, which we've ruled out.
* musl uses them without checking the C standard in use. So suppressing
* the check here seems reasonable.
*/
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wvariadic-macros"
/* These syscall macros were copied from musl. */
#define __scc(x) ((__sc_word_t)(x))
#define __syscall0(n) __do_syscall0(n)
#define __syscall1(n,a) __do_syscall1(n,__scc(a))
#define __syscall2(n,a,b) __do_syscall2(n,__scc(a),__scc(b))
#define __syscall3(n,a,b,c) __do_syscall3(n,__scc(a),__scc(b),__scc(c))
#define __syscall4(n,a,b,c,d) __do_syscall4(n,__scc(a),__scc(b),__scc(c),__scc(d))
#define __syscall5(n,a,b,c,d,e) __do_syscall5(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e))
#define __syscall6(n,a,b,c,d,e,f) __do_syscall6(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f))
#define __syscall7(n,a,b,c,d,e,f,g) __do_syscall7(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f),__scc(g))
#define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
#define __SYSCALL_NARGS(...) __SYSCALL_NARGS_X(__VA_ARGS__,7,6,5,4,3,2,1,0,)
#define __SYSCALL_CONCAT_X(a,b) a##b
#define __SYSCALL_CONCAT(a,b) __SYSCALL_CONCAT_X(a,b)
#define __SYSCALL_DISP(b,...) __SYSCALL_CONCAT(b,__SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)
#define __syscall(...) __SYSCALL_DISP(__syscall,__VA_ARGS__)
#define syscall(...) __do_syscall_ret(__syscall(__VA_ARGS__))
#pragma GCC diagnostic pop
#endif
#ifdef __cplusplus
}
#endif
#endif /* _MLIBC_SYSCALL_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,12 @@
#ifndef MLIBC_THREAD_ENTRY
#include <mlibc/tcb.hpp>
extern "C" int __mlibc_spawn_thread(int flags, void *stack, void *pid_out, void *child_tid, void *tcb);
extern "C" void __mlibc_enter_thread(void *entry, void *user_arg);
namespace mlibc {
void *prepare_stack(void *entry, void *user_arg);
}
#endif // MLIBC_THREAD_ENTRY
@@ -0,0 +1,14 @@
#ifndef _SYS_SYSCALL_H
#define _SYS_SYSCALL_H
/* On GNU/Linux, this header provides includes __NR_-prefixed syscall numbers,
* and their SYS_ aliases. We defer to kernel headers for the numbers
* (linux-headers, or an autogenerated stub while building), and an
* autogenerated file containing SYS_ defines.
*/
/* clang-format off */
#include <linux/unistd.h>
#include <bits/syscall_aliases.h>
/* clang-format on */
#endif /* _SYS_SYSCALL_H */
@@ -0,0 +1 @@
#include <sys/syscall.h>
@@ -0,0 +1,117 @@
#include <sys/syscall.h>
#include <bits/syscall.h>
using sc_word_t = __sc_word_t;
sc_word_t __do_syscall0(long sc) {
register int sc_reg asm("a7") = sc;
register sc_word_t ret asm("a0");
asm volatile ("syscall 0" : "=r"(ret) : "r"(sc_reg) : "memory", "a1");
return ret;
}
sc_word_t __do_syscall1(long sc,
sc_word_t arg1) {
register int sc_reg asm("a7") = sc;
register sc_word_t arg1_reg asm("a0") = arg1;
register sc_word_t ret asm("a0");
asm volatile ("syscall 0" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg)
: "memory", "a1");
return ret;
}
sc_word_t __do_syscall2(long sc,
sc_word_t arg1, sc_word_t arg2) {
register int sc_reg asm("a7") = sc;
register sc_word_t arg1_reg asm("a0") = arg1;
register sc_word_t arg2_reg asm("a1") = arg2;
register sc_word_t ret asm("a0");
asm volatile ("syscall 0" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg),
"r"(arg2_reg)
: "memory");
return ret;
}
sc_word_t __do_syscall3(long sc,
sc_word_t arg1, sc_word_t arg2, sc_word_t arg3) {
register int sc_reg asm("a7") = sc;
register sc_word_t arg1_reg asm("a0") = arg1;
register sc_word_t arg2_reg asm("a1") = arg2;
register sc_word_t arg3_reg asm("a2") = arg3;
register sc_word_t ret asm("a0");
asm volatile ("syscall 0" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg),
"r"(arg2_reg),
"r"(arg3_reg)
: "memory");
return ret;
}
sc_word_t __do_syscall4(long sc,
sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4) {
register int sc_reg asm("a7") = sc;
register sc_word_t arg1_reg asm("a0") = arg1;
register sc_word_t arg2_reg asm("a1") = arg2;
register sc_word_t arg3_reg asm("a2") = arg3;
register sc_word_t arg4_reg asm("a3") = arg4;
register sc_word_t ret asm("a0");
asm volatile ("syscall 0" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg),
"r"(arg2_reg),
"r"(arg3_reg),
"r"(arg4_reg)
: "memory");
return ret;
}
sc_word_t __do_syscall5(long sc,
sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4, sc_word_t arg5) {
register int sc_reg asm("a7") = sc;
register sc_word_t arg1_reg asm("a0") = arg1;
register sc_word_t arg2_reg asm("a1") = arg2;
register sc_word_t arg3_reg asm("a2") = arg3;
register sc_word_t arg4_reg asm("a3") = arg4;
register sc_word_t arg5_reg asm("a4") = arg5;
register sc_word_t ret asm("a0");
asm volatile ("syscall 0" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg),
"r"(arg2_reg),
"r"(arg3_reg),
"r"(arg4_reg),
"r"(arg5_reg)
: "memory");
return ret;
}
sc_word_t __do_syscall6(long sc,
sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4, sc_word_t arg5, sc_word_t arg6) {
register int sc_reg asm("a7") = sc;
register sc_word_t arg1_reg asm("a0") = arg1;
register sc_word_t arg2_reg asm("a1") = arg2;
register sc_word_t arg3_reg asm("a2") = arg3;
register sc_word_t arg4_reg asm("a3") = arg4;
register sc_word_t arg5_reg asm("a4") = arg5;
register sc_word_t arg6_reg asm("a5") = arg6;
register sc_word_t ret asm("a0");
asm volatile ("syscall 0" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg),
"r"(arg2_reg),
"r"(arg3_reg),
"r"(arg4_reg),
"r"(arg5_reg),
"r"(arg6_reg)
: "memory"
);
return ret;
}
@@ -0,0 +1,30 @@
.section .text
.global __mlibc_do_asm_cp_syscall
.global __mlibc_syscall_begin
.global __mlibc_syscall_end
.type __mlibc_do_asm_cp_syscall, "function"
__mlibc_do_asm_cp_syscall:
st.d $a7, $sp, -8
move $a7, $a0
move $a0, $a1
move $a1, $a2
move $a2, $a3
move $a3, $a4
move $a4, $a5
move $a5, $a6
move $a6, $a7
ld.w $t0, $tp, -96 // Tcb::cancelBits. See asserts in tcb.hpp.
__mlibc_syscall_begin:
// tcbCancelEnableBit && tcbCancelTriggerBit
addi.d $t1, $r0, (1 << 0) | (1 << 2)
and $t0, $t0, $t1
beq $t0, $t1, cancel
syscall 0
__mlibc_syscall_end:
ret
cancel:
la.local $t2, __mlibc_do_cancel
jr $t2
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,11 @@
.extern __mlibc_entry@plt
.section .text
.global _start
_start:
move $a0, $sp
la $a1, main
bl %plt(__mlibc_entry)
break 0
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,11 @@
.extern __mlibc_entry
.section .text
.global _start
_start:
move $a0, $sp
la $a1, main
b __mlibc_entry
break 0
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,12 @@
.section .text
.global __mlibc_signal_restore
.type __mlibc_signal_restore, @function
__mlibc_signal_restore:
.global __mlibc_signal_restore_rt
.type __mlibc_signal_restore_rt, @function
__mlibc_signal_restore_rt:
li.w $a7, 139 // __NR_rt_sigreturn
syscall 0
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,323 @@
#ifndef __MLIBC_SYSCALLNOS_h
#define __MLIBC_SYSCALLNOS_h
/* This file is autogenerated. Don't bother. */
/* Generator script: sysdeps/linux/update-syscall-list.py. */
#define __NR_io_setup 0
#define __NR_io_destroy 1
#define __NR_io_submit 2
#define __NR_io_cancel 3
#define __NR_io_getevents 4
#define __NR_setxattr 5
#define __NR_lsetxattr 6
#define __NR_fsetxattr 7
#define __NR_getxattr 8
#define __NR_lgetxattr 9
#define __NR_fgetxattr 10
#define __NR_listxattr 11
#define __NR_llistxattr 12
#define __NR_flistxattr 13
#define __NR_removexattr 14
#define __NR_lremovexattr 15
#define __NR_fremovexattr 16
#define __NR_getcwd 17
#define __NR_lookup_dcookie 18
#define __NR_eventfd2 19
#define __NR_epoll_create1 20
#define __NR_epoll_ctl 21
#define __NR_epoll_pwait 22
#define __NR_dup 23
#define __NR_dup3 24
#define __NR_fcntl 25
#define __NR_inotify_init1 26
#define __NR_inotify_add_watch 27
#define __NR_inotify_rm_watch 28
#define __NR_ioctl 29
#define __NR_ioprio_set 30
#define __NR_ioprio_get 31
#define __NR_flock 32
#define __NR_mknodat 33
#define __NR_mkdirat 34
#define __NR_unlinkat 35
#define __NR_symlinkat 36
#define __NR_linkat 37
#define __NR_umount2 39
#define __NR_mount 40
#define __NR_pivot_root 41
#define __NR_nfsservctl 42
#define __NR_statfs 43
#define __NR_fstatfs 44
#define __NR_truncate 45
#define __NR_ftruncate 46
#define __NR_fallocate 47
#define __NR_faccessat 48
#define __NR_chdir 49
#define __NR_fchdir 50
#define __NR_chroot 51
#define __NR_fchmod 52
#define __NR_fchmodat 53
#define __NR_fchownat 54
#define __NR_fchown 55
#define __NR_openat 56
#define __NR_close 57
#define __NR_vhangup 58
#define __NR_pipe2 59
#define __NR_quotactl 60
#define __NR_getdents64 61
#define __NR_lseek 62
#define __NR_read 63
#define __NR_write 64
#define __NR_readv 65
#define __NR_writev 66
#define __NR_pread64 67
#define __NR_pwrite64 68
#define __NR_preadv 69
#define __NR_pwritev 70
#define __NR_sendfile 71
#define __NR_pselect6 72
#define __NR_ppoll 73
#define __NR_signalfd4 74
#define __NR_vmsplice 75
#define __NR_splice 76
#define __NR_tee 77
#define __NR_readlinkat 78
#define __NR_newfstatat 79
#define __NR_fstat 80
#define __NR_sync 81
#define __NR_fsync 82
#define __NR_fdatasync 83
#define __NR_sync_file_range 84
#define __NR_timerfd_create 85
#define __NR_timerfd_settime 86
#define __NR_timerfd_gettime 87
#define __NR_utimensat 88
#define __NR_acct 89
#define __NR_capget 90
#define __NR_capset 91
#define __NR_personality 92
#define __NR_exit 93
#define __NR_exit_group 94
#define __NR_waitid 95
#define __NR_set_tid_address 96
#define __NR_unshare 97
#define __NR_futex 98
#define __NR_set_robust_list 99
#define __NR_get_robust_list 100
#define __NR_nanosleep 101
#define __NR_getitimer 102
#define __NR_setitimer 103
#define __NR_kexec_load 104
#define __NR_init_module 105
#define __NR_delete_module 106
#define __NR_timer_create 107
#define __NR_timer_gettime 108
#define __NR_timer_getoverrun 109
#define __NR_timer_settime 110
#define __NR_timer_delete 111
#define __NR_clock_settime 112
#define __NR_clock_gettime 113
#define __NR_clock_getres 114
#define __NR_clock_nanosleep 115
#define __NR_syslog 116
#define __NR_ptrace 117
#define __NR_sched_setparam 118
#define __NR_sched_setscheduler 119
#define __NR_sched_getscheduler 120
#define __NR_sched_getparam 121
#define __NR_sched_setaffinity 122
#define __NR_sched_getaffinity 123
#define __NR_sched_yield 124
#define __NR_sched_get_priority_max 125
#define __NR_sched_get_priority_min 126
#define __NR_sched_rr_get_interval 127
#define __NR_restart_syscall 128
#define __NR_kill 129
#define __NR_tkill 130
#define __NR_tgkill 131
#define __NR_sigaltstack 132
#define __NR_rt_sigsuspend 133
#define __NR_rt_sigaction 134
#define __NR_rt_sigprocmask 135
#define __NR_rt_sigpending 136
#define __NR_rt_sigtimedwait 137
#define __NR_rt_sigqueueinfo 138
#define __NR_rt_sigreturn 139
#define __NR_setpriority 140
#define __NR_getpriority 141
#define __NR_reboot 142
#define __NR_setregid 143
#define __NR_setgid 144
#define __NR_setreuid 145
#define __NR_setuid 146
#define __NR_setresuid 147
#define __NR_getresuid 148
#define __NR_setresgid 149
#define __NR_getresgid 150
#define __NR_setfsuid 151
#define __NR_setfsgid 152
#define __NR_times 153
#define __NR_setpgid 154
#define __NR_getpgid 155
#define __NR_getsid 156
#define __NR_setsid 157
#define __NR_getgroups 158
#define __NR_setgroups 159
#define __NR_uname 160
#define __NR_sethostname 161
#define __NR_setdomainname 162
#define __NR_getrusage 165
#define __NR_umask 166
#define __NR_prctl 167
#define __NR_getcpu 168
#define __NR_gettimeofday 169
#define __NR_settimeofday 170
#define __NR_adjtimex 171
#define __NR_getpid 172
#define __NR_getppid 173
#define __NR_getuid 174
#define __NR_geteuid 175
#define __NR_getgid 176
#define __NR_getegid 177
#define __NR_gettid 178
#define __NR_sysinfo 179
#define __NR_mq_open 180
#define __NR_mq_unlink 181
#define __NR_mq_timedsend 182
#define __NR_mq_timedreceive 183
#define __NR_mq_notify 184
#define __NR_mq_getsetattr 185
#define __NR_msgget 186
#define __NR_msgctl 187
#define __NR_msgrcv 188
#define __NR_msgsnd 189
#define __NR_semget 190
#define __NR_semctl 191
#define __NR_semtimedop 192
#define __NR_semop 193
#define __NR_shmget 194
#define __NR_shmctl 195
#define __NR_shmat 196
#define __NR_shmdt 197
#define __NR_socket 198
#define __NR_socketpair 199
#define __NR_bind 200
#define __NR_listen 201
#define __NR_accept 202
#define __NR_connect 203
#define __NR_getsockname 204
#define __NR_getpeername 205
#define __NR_sendto 206
#define __NR_recvfrom 207
#define __NR_setsockopt 208
#define __NR_getsockopt 209
#define __NR_shutdown 210
#define __NR_sendmsg 211
#define __NR_recvmsg 212
#define __NR_readahead 213
#define __NR_brk 214
#define __NR_munmap 215
#define __NR_mremap 216
#define __NR_add_key 217
#define __NR_request_key 218
#define __NR_keyctl 219
#define __NR_clone 220
#define __NR_execve 221
#define __NR_mmap 222
#define __NR_fadvise64 223
#define __NR_swapon 224
#define __NR_swapoff 225
#define __NR_mprotect 226
#define __NR_msync 227
#define __NR_mlock 228
#define __NR_munlock 229
#define __NR_mlockall 230
#define __NR_munlockall 231
#define __NR_mincore 232
#define __NR_madvise 233
#define __NR_remap_file_pages 234
#define __NR_mbind 235
#define __NR_get_mempolicy 236
#define __NR_set_mempolicy 237
#define __NR_migrate_pages 238
#define __NR_move_pages 239
#define __NR_rt_tgsigqueueinfo 240
#define __NR_perf_event_open 241
#define __NR_accept4 242
#define __NR_recvmmsg 243
#define __NR_wait4 260
#define __NR_prlimit64 261
#define __NR_fanotify_init 262
#define __NR_fanotify_mark 263
#define __NR_name_to_handle_at 264
#define __NR_open_by_handle_at 265
#define __NR_clock_adjtime 266
#define __NR_syncfs 267
#define __NR_setns 268
#define __NR_sendmmsg 269
#define __NR_process_vm_readv 270
#define __NR_process_vm_writev 271
#define __NR_kcmp 272
#define __NR_finit_module 273
#define __NR_sched_setattr 274
#define __NR_sched_getattr 275
#define __NR_renameat2 276
#define __NR_seccomp 277
#define __NR_getrandom 278
#define __NR_memfd_create 279
#define __NR_bpf 280
#define __NR_execveat 281
#define __NR_userfaultfd 282
#define __NR_membarrier 283
#define __NR_mlock2 284
#define __NR_copy_file_range 285
#define __NR_preadv2 286
#define __NR_pwritev2 287
#define __NR_pkey_mprotect 288
#define __NR_pkey_alloc 289
#define __NR_pkey_free 290
#define __NR_statx 291
#define __NR_io_pgetevents 292
#define __NR_rseq 293
#define __NR_kexec_file_load 294
#define __NR_pidfd_send_signal 424
#define __NR_io_uring_setup 425
#define __NR_io_uring_enter 426
#define __NR_io_uring_register 427
#define __NR_open_tree 428
#define __NR_move_mount 429
#define __NR_fsopen 430
#define __NR_fsconfig 431
#define __NR_fsmount 432
#define __NR_fspick 433
#define __NR_pidfd_open 434
#define __NR_clone3 435
#define __NR_close_range 436
#define __NR_openat2 437
#define __NR_pidfd_getfd 438
#define __NR_faccessat2 439
#define __NR_process_madvise 440
#define __NR_epoll_pwait2 441
#define __NR_mount_setattr 442
#define __NR_quotactl_fd 443
#define __NR_landlock_create_ruleset 444
#define __NR_landlock_add_rule 445
#define __NR_landlock_restrict_self 446
#define __NR_process_mrelease 448
#define __NR_futex_waitv 449
#define __NR_set_mempolicy_home_node 450
#define __NR_cachestat 451
#define __NR_fchmodat2 452
#define __NR_map_shadow_stack 453
#define __NR_futex_wake 454
#define __NR_futex_wait 455
#define __NR_futex_requeue 456
#define __NR_statmount 457
#define __NR_listmount 458
#define __NR_lsm_get_self_attr 459
#define __NR_lsm_set_self_attr 460
#define __NR_lsm_list_modules 461
#define __NR_mseal 462
#define __NR_setxattrat 463
#define __NR_getxattrat 464
#define __NR_listxattrat 465
#define __NR_removexattrat 466
#endif /* __MLIBC_SYSCALLNOS_h */
@@ -0,0 +1,24 @@
.section .text
.global __mlibc_spawn_thread
.type __mlibc_spawn_thread, "function"
__mlibc_spawn_thread:
// __mlibc_spawn_thread(flags, stack, pid_out, child_tid, tls)
// a0, a1, a2, a3, a4
// syscall(NR_clone, flags, stack, ptid, ctid, tls)
// a7, a0, a1, a2, a3, a4
addi.d $a7, $zero, 220 // NR_clone
syscall 0
bnez $a0, .parent
ld.d $a0, $sp, 0
ld.d $a1, $sp, 8
addi.d $sp, $sp, 8
bstrins.d $sp, $sp, 3, 0
b __mlibc_enter_thread
break 0
.parent:
ret
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,117 @@
#include <sys/syscall.h>
#include <bits/syscall.h>
using sc_word_t = __sc_word_t;
sc_word_t __do_syscall0(long sc) {
register int sc_reg asm("d0") = sc;
register sc_word_t ret asm("d0");
asm volatile ("trap #0" : "=r"(ret) : "r"(sc_reg) : "memory");
return ret;
}
sc_word_t __do_syscall1(long sc,
sc_word_t arg1) {
register int sc_reg asm("d0") = sc;
register sc_word_t arg1_reg asm("d1") = arg1;
register sc_word_t ret asm("d0");
asm volatile ("trap #0" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg)
: "memory");
return ret;
}
sc_word_t __do_syscall2(long sc,
sc_word_t arg1, sc_word_t arg2) {
register int sc_reg asm("d0") = sc;
register sc_word_t arg1_reg asm("d1") = arg1;
register sc_word_t arg2_reg asm("d2") = arg2;
register sc_word_t ret asm("d0");
asm volatile ("trap #0" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg),
"r"(arg2_reg)
: "memory");
return ret;
}
sc_word_t __do_syscall3(long sc,
sc_word_t arg1, sc_word_t arg2, sc_word_t arg3) {
register int sc_reg asm("d0") = sc;
register sc_word_t arg1_reg asm("d1") = arg1;
register sc_word_t arg2_reg asm("d2") = arg2;
register sc_word_t arg3_reg asm("d3") = arg3;
register sc_word_t ret asm("d0");
asm volatile ("trap #0" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg),
"r"(arg2_reg),
"r"(arg3_reg)
: "memory");
return ret;
}
sc_word_t __do_syscall4(long sc,
sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4) {
register int sc_reg asm("d0") = sc;
register sc_word_t arg1_reg asm("d1") = arg1;
register sc_word_t arg2_reg asm("d2") = arg2;
register sc_word_t arg3_reg asm("d3") = arg3;
register sc_word_t arg4_reg asm("d4") = arg4;
register sc_word_t ret asm("d0");
asm volatile ("trap #0" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg),
"r"(arg2_reg),
"r"(arg3_reg),
"r"(arg4_reg)
: "memory");
return ret;
}
sc_word_t __do_syscall5(long sc,
sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4, sc_word_t arg5) {
register int sc_reg asm("d0") = sc;
register sc_word_t arg1_reg asm("d1") = arg1;
register sc_word_t arg2_reg asm("d2") = arg2;
register sc_word_t arg3_reg asm("d3") = arg3;
register sc_word_t arg4_reg asm("d4") = arg4;
register sc_word_t arg5_reg asm("d5") = arg5;
register sc_word_t ret asm("d0");
asm volatile ("trap #0" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg),
"r"(arg2_reg),
"r"(arg3_reg),
"r"(arg4_reg),
"r"(arg5_reg)
: "memory");
return ret;
}
sc_word_t __do_syscall6(long sc,
sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4, sc_word_t arg5, sc_word_t arg6) {
register int sc_reg asm("d0") = sc;
register sc_word_t arg1_reg asm("d1") = arg1;
register sc_word_t arg2_reg asm("d2") = arg2;
register sc_word_t arg3_reg asm("d3") = arg3;
register sc_word_t arg4_reg asm("d4") = arg4;
register sc_word_t arg5_reg asm("d5") = arg5;
register sc_word_t arg6_reg asm("a0") = arg6;
register sc_word_t ret asm("d0");
asm volatile ("trap #0" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg),
"r"(arg2_reg),
"r"(arg3_reg),
"r"(arg4_reg),
"r"(arg5_reg),
"r"(arg6_reg)
: "memory"
);
return ret;
}
@@ -0,0 +1,28 @@
.section .text
.global __mlibc_do_asm_cp_syscall
.global __mlibc_syscall_begin
.global __mlibc_syscall_end
.type __mlibc_do_asm_cp_syscall, "function"
__mlibc_do_asm_cp_syscall:
movem.l %d2-%d5, -(%sp)
jbsr __m68k_read_tp@PLTPC
/* cancelBits is at TP - 0x7030; LSB at -0x702d */
move.b -0x702d(%a0), %d0
__mlibc_syscall_begin:
/* tcbCancelEnableBit && tcbCancelTriggerBit */
andi.b #0x5, %d0
cmpi.b #0x5, %d0
beq cancel
movem.l 20(%sp), %d0-%d5/%a0
trap #0
__mlibc_syscall_end:
movem.l (%sp)+, %d2-%d5
rts
cancel:
movem.l (%sp)+, %d2-%d5
jbsr __mlibc_do_cancel@PLTPC
illegal
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,16 @@
.section .text
.global _start
.type _start, %function
.type main, %function
.type __mlibc_entry, %function
_start:
suba.l %fp, %fp
move.l %sp, %d0
lea _GLOBAL_OFFSET_TABLE_@GOTPC (%pc), %a5
move.l main@GOT(%a5), -(%sp)
move.l %d0, -(%sp)
jbsr __mlibc_entry@PLTPC
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,15 @@
.section .text
.global _start
.type _start, %function
.type main, %function
.type __mlibc_entry, %function
_start:
suba.l %fp, %fp
move.l %sp, %d0
move.l #main, -(%sp)
move.l %d0, -(%sp)
jsr __mlibc_entry
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,9 @@
.section ".init"
.global _init
_init:
.section ".fini"
.globl _fini
_fini:
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,7 @@
.section .init
rts
.section .fini
rts
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,19 @@
.section .text
.global __mlibc_signal_restore
.type __mlibc_signal_restore, @function
__mlibc_signal_restore:
move.l (%sp)+, %d1
move.l #119, %d0
trap #0
illegal
.global __mlibc_signal_restore_rt
.type __mlibc_signal_restore_rt, @function
__mlibc_signal_restore_rt:
move.l (%sp)+, %d1
move.l #173, %d0
trap #0
illegal
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,442 @@
#ifndef __MLIBC_SYSCALLNOS_h
#define __MLIBC_SYSCALLNOS_h
/* This file is autogenerated. Don't bother. */
/* Generator script: sysdeps/linux/update-syscall-list.py. */
#define __NR_restart_syscall 0
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_write 4
#define __NR_open 5
#define __NR_close 6
#define __NR_waitpid 7
#define __NR_creat 8
#define __NR_link 9
#define __NR_unlink 10
#define __NR_execve 11
#define __NR_chdir 12
#define __NR_time 13
#define __NR_mknod 14
#define __NR_chmod 15
#define __NR_chown 16
#define __NR_oldstat 18
#define __NR_lseek 19
#define __NR_getpid 20
#define __NR_mount 21
#define __NR_umount 22
#define __NR_setuid 23
#define __NR_getuid 24
#define __NR_stime 25
#define __NR_ptrace 26
#define __NR_alarm 27
#define __NR_oldfstat 28
#define __NR_pause 29
#define __NR_utime 30
#define __NR_access 33
#define __NR_nice 34
#define __NR_sync 36
#define __NR_kill 37
#define __NR_rename 38
#define __NR_mkdir 39
#define __NR_rmdir 40
#define __NR_dup 41
#define __NR_pipe 42
#define __NR_times 43
#define __NR_brk 45
#define __NR_setgid 46
#define __NR_getgid 47
#define __NR_signal 48
#define __NR_geteuid 49
#define __NR_getegid 50
#define __NR_acct 51
#define __NR_umount2 52
#define __NR_ioctl 54
#define __NR_fcntl 55
#define __NR_setpgid 57
#define __NR_umask 60
#define __NR_chroot 61
#define __NR_ustat 62
#define __NR_dup2 63
#define __NR_getppid 64
#define __NR_getpgrp 65
#define __NR_setsid 66
#define __NR_sigaction 67
#define __NR_sgetmask 68
#define __NR_ssetmask 69
#define __NR_setreuid 70
#define __NR_setregid 71
#define __NR_sigsuspend 72
#define __NR_sigpending 73
#define __NR_sethostname 74
#define __NR_setrlimit 75
#define __NR_getrlimit 76
#define __NR_getrusage 77
#define __NR_gettimeofday 78
#define __NR_settimeofday 79
#define __NR_getgroups 80
#define __NR_setgroups 81
#define __NR_select 82
#define __NR_symlink 83
#define __NR_oldlstat 84
#define __NR_readlink 85
#define __NR_uselib 86
#define __NR_swapon 87
#define __NR_reboot 88
#define __NR_readdir 89
#define __NR_mmap 90
#define __NR_munmap 91
#define __NR_truncate 92
#define __NR_ftruncate 93
#define __NR_fchmod 94
#define __NR_fchown 95
#define __NR_getpriority 96
#define __NR_setpriority 97
#define __NR_statfs 99
#define __NR_fstatfs 100
#define __NR_socketcall 102
#define __NR_syslog 103
#define __NR_setitimer 104
#define __NR_getitimer 105
#define __NR_stat 106
#define __NR_lstat 107
#define __NR_fstat 108
#define __NR_vhangup 111
#define __NR_wait4 114
#define __NR_swapoff 115
#define __NR_sysinfo 116
#define __NR_ipc 117
#define __NR_fsync 118
#define __NR_sigreturn 119
#define __NR_clone 120
#define __NR_setdomainname 121
#define __NR_uname 122
#define __NR_cacheflush 123
#define __NR_adjtimex 124
#define __NR_mprotect 125
#define __NR_sigprocmask 126
#define __NR_create_module 127
#define __NR_init_module 128
#define __NR_delete_module 129
#define __NR_get_kernel_syms 130
#define __NR_quotactl 131
#define __NR_getpgid 132
#define __NR_fchdir 133
#define __NR_bdflush 134
#define __NR_sysfs 135
#define __NR_personality 136
#define __NR_setfsuid 138
#define __NR_setfsgid 139
#define __NR__llseek 140
#define __NR_getdents 141
#define __NR__newselect 142
#define __NR_flock 143
#define __NR_msync 144
#define __NR_readv 145
#define __NR_writev 146
#define __NR_getsid 147
#define __NR_fdatasync 148
#define __NR__sysctl 149
#define __NR_mlock 150
#define __NR_munlock 151
#define __NR_mlockall 152
#define __NR_munlockall 153
#define __NR_sched_setparam 154
#define __NR_sched_getparam 155
#define __NR_sched_setscheduler 156
#define __NR_sched_getscheduler 157
#define __NR_sched_yield 158
#define __NR_sched_get_priority_max 159
#define __NR_sched_get_priority_min 160
#define __NR_sched_rr_get_interval 161
#define __NR_nanosleep 162
#define __NR_mremap 163
#define __NR_setresuid 164
#define __NR_getresuid 165
#define __NR_getpagesize 166
#define __NR_query_module 167
#define __NR_poll 168
#define __NR_nfsservctl 169
#define __NR_setresgid 170
#define __NR_getresgid 171
#define __NR_prctl 172
#define __NR_rt_sigreturn 173
#define __NR_rt_sigaction 174
#define __NR_rt_sigprocmask 175
#define __NR_rt_sigpending 176
#define __NR_rt_sigtimedwait 177
#define __NR_rt_sigqueueinfo 178
#define __NR_rt_sigsuspend 179
#define __NR_pread64 180
#define __NR_pwrite64 181
#define __NR_lchown 182
#define __NR_getcwd 183
#define __NR_capget 184
#define __NR_capset 185
#define __NR_sigaltstack 186
#define __NR_sendfile 187
#define __NR_getpmsg 188
#define __NR_vfork 190
#define __NR_ugetrlimit 191
#define __NR_mmap2 192
#define __NR_truncate64 193
#define __NR_ftruncate64 194
#define __NR_stat64 195
#define __NR_lstat64 196
#define __NR_fstat64 197
#define __NR_chown32 198
#define __NR_getuid32 199
#define __NR_getgid32 200
#define __NR_geteuid32 201
#define __NR_getegid32 202
#define __NR_setreuid32 203
#define __NR_setregid32 204
#define __NR_getgroups32 205
#define __NR_setgroups32 206
#define __NR_fchown32 207
#define __NR_setresuid32 208
#define __NR_getresuid32 209
#define __NR_setresgid32 210
#define __NR_getresgid32 211
#define __NR_lchown32 212
#define __NR_setuid32 213
#define __NR_setgid32 214
#define __NR_setfsuid32 215
#define __NR_setfsgid32 216
#define __NR_pivot_root 217
#define __NR_getdents64 220
#define __NR_gettid 221
#define __NR_tkill 222
#define __NR_setxattr 223
#define __NR_lsetxattr 224
#define __NR_fsetxattr 225
#define __NR_getxattr 226
#define __NR_lgetxattr 227
#define __NR_fgetxattr 228
#define __NR_listxattr 229
#define __NR_llistxattr 230
#define __NR_flistxattr 231
#define __NR_removexattr 232
#define __NR_lremovexattr 233
#define __NR_fremovexattr 234
#define __NR_futex 235
#define __NR_sendfile64 236
#define __NR_mincore 237
#define __NR_madvise 238
#define __NR_fcntl64 239
#define __NR_readahead 240
#define __NR_io_setup 241
#define __NR_io_destroy 242
#define __NR_io_getevents 243
#define __NR_io_submit 244
#define __NR_io_cancel 245
#define __NR_fadvise64 246
#define __NR_exit_group 247
#define __NR_lookup_dcookie 248
#define __NR_epoll_create 249
#define __NR_epoll_ctl 250
#define __NR_epoll_wait 251
#define __NR_remap_file_pages 252
#define __NR_set_tid_address 253
#define __NR_timer_create 254
#define __NR_timer_settime 255
#define __NR_timer_gettime 256
#define __NR_timer_getoverrun 257
#define __NR_timer_delete 258
#define __NR_clock_settime 259
#define __NR_clock_gettime 260
#define __NR_clock_getres 261
#define __NR_clock_nanosleep 262
#define __NR_statfs64 263
#define __NR_fstatfs64 264
#define __NR_tgkill 265
#define __NR_utimes 266
#define __NR_fadvise64_64 267
#define __NR_mbind 268
#define __NR_get_mempolicy 269
#define __NR_set_mempolicy 270
#define __NR_mq_open 271
#define __NR_mq_unlink 272
#define __NR_mq_timedsend 273
#define __NR_mq_timedreceive 274
#define __NR_mq_notify 275
#define __NR_mq_getsetattr 276
#define __NR_waitid 277
#define __NR_add_key 279
#define __NR_request_key 280
#define __NR_keyctl 281
#define __NR_ioprio_set 282
#define __NR_ioprio_get 283
#define __NR_inotify_init 284
#define __NR_inotify_add_watch 285
#define __NR_inotify_rm_watch 286
#define __NR_migrate_pages 287
#define __NR_openat 288
#define __NR_mkdirat 289
#define __NR_mknodat 290
#define __NR_fchownat 291
#define __NR_futimesat 292
#define __NR_fstatat64 293
#define __NR_unlinkat 294
#define __NR_renameat 295
#define __NR_linkat 296
#define __NR_symlinkat 297
#define __NR_readlinkat 298
#define __NR_fchmodat 299
#define __NR_faccessat 300
#define __NR_pselect6 301
#define __NR_ppoll 302
#define __NR_unshare 303
#define __NR_set_robust_list 304
#define __NR_get_robust_list 305
#define __NR_splice 306
#define __NR_sync_file_range 307
#define __NR_tee 308
#define __NR_vmsplice 309
#define __NR_move_pages 310
#define __NR_sched_setaffinity 311
#define __NR_sched_getaffinity 312
#define __NR_kexec_load 313
#define __NR_getcpu 314
#define __NR_epoll_pwait 315
#define __NR_utimensat 316
#define __NR_signalfd 317
#define __NR_timerfd_create 318
#define __NR_eventfd 319
#define __NR_fallocate 320
#define __NR_timerfd_settime 321
#define __NR_timerfd_gettime 322
#define __NR_signalfd4 323
#define __NR_eventfd2 324
#define __NR_epoll_create1 325
#define __NR_dup3 326
#define __NR_pipe2 327
#define __NR_inotify_init1 328
#define __NR_preadv 329
#define __NR_pwritev 330
#define __NR_rt_tgsigqueueinfo 331
#define __NR_perf_event_open 332
#define __NR_get_thread_area 333
#define __NR_set_thread_area 334
#define __NR_atomic_cmpxchg_32 335
#define __NR_atomic_barrier 336
#define __NR_fanotify_init 337
#define __NR_fanotify_mark 338
#define __NR_prlimit64 339
#define __NR_name_to_handle_at 340
#define __NR_open_by_handle_at 341
#define __NR_clock_adjtime 342
#define __NR_syncfs 343
#define __NR_setns 344
#define __NR_process_vm_readv 345
#define __NR_process_vm_writev 346
#define __NR_kcmp 347
#define __NR_finit_module 348
#define __NR_sched_setattr 349
#define __NR_sched_getattr 350
#define __NR_renameat2 351
#define __NR_getrandom 352
#define __NR_memfd_create 353
#define __NR_bpf 354
#define __NR_execveat 355
#define __NR_socket 356
#define __NR_socketpair 357
#define __NR_bind 358
#define __NR_connect 359
#define __NR_listen 360
#define __NR_accept4 361
#define __NR_getsockopt 362
#define __NR_setsockopt 363
#define __NR_getsockname 364
#define __NR_getpeername 365
#define __NR_sendto 366
#define __NR_sendmsg 367
#define __NR_recvfrom 368
#define __NR_recvmsg 369
#define __NR_shutdown 370
#define __NR_recvmmsg 371
#define __NR_sendmmsg 372
#define __NR_userfaultfd 373
#define __NR_membarrier 374
#define __NR_mlock2 375
#define __NR_copy_file_range 376
#define __NR_preadv2 377
#define __NR_pwritev2 378
#define __NR_statx 379
#define __NR_seccomp 380
#define __NR_pkey_mprotect 381
#define __NR_pkey_alloc 382
#define __NR_pkey_free 383
#define __NR_rseq 384
#define __NR_semget 393
#define __NR_semctl 394
#define __NR_shmget 395
#define __NR_shmctl 396
#define __NR_shmat 397
#define __NR_shmdt 398
#define __NR_msgget 399
#define __NR_msgsnd 400
#define __NR_msgrcv 401
#define __NR_msgctl 402
#define __NR_clock_gettime64 403
#define __NR_clock_settime64 404
#define __NR_clock_adjtime64 405
#define __NR_clock_getres_time64 406
#define __NR_clock_nanosleep_time64 407
#define __NR_timer_gettime64 408
#define __NR_timer_settime64 409
#define __NR_timerfd_gettime64 410
#define __NR_timerfd_settime64 411
#define __NR_utimensat_time64 412
#define __NR_pselect6_time64 413
#define __NR_ppoll_time64 414
#define __NR_io_pgetevents_time64 416
#define __NR_recvmmsg_time64 417
#define __NR_mq_timedsend_time64 418
#define __NR_mq_timedreceive_time64 419
#define __NR_semtimedop_time64 420
#define __NR_rt_sigtimedwait_time64 421
#define __NR_futex_time64 422
#define __NR_sched_rr_get_interval_time64 423
#define __NR_pidfd_send_signal 424
#define __NR_io_uring_setup 425
#define __NR_io_uring_enter 426
#define __NR_io_uring_register 427
#define __NR_open_tree 428
#define __NR_move_mount 429
#define __NR_fsopen 430
#define __NR_fsconfig 431
#define __NR_fsmount 432
#define __NR_fspick 433
#define __NR_pidfd_open 434
#define __NR_clone3 435
#define __NR_close_range 436
#define __NR_openat2 437
#define __NR_pidfd_getfd 438
#define __NR_faccessat2 439
#define __NR_process_madvise 440
#define __NR_epoll_pwait2 441
#define __NR_mount_setattr 442
#define __NR_quotactl_fd 443
#define __NR_landlock_create_ruleset 444
#define __NR_landlock_add_rule 445
#define __NR_landlock_restrict_self 446
#define __NR_process_mrelease 448
#define __NR_futex_waitv 449
#define __NR_set_mempolicy_home_node 450
#define __NR_cachestat 451
#define __NR_fchmodat2 452
#define __NR_map_shadow_stack 453
#define __NR_futex_wake 454
#define __NR_futex_wait 455
#define __NR_futex_requeue 456
#define __NR_statmount 457
#define __NR_listmount 458
#define __NR_lsm_get_self_attr 459
#define __NR_lsm_set_self_attr 460
#define __NR_lsm_list_modules 461
#define __NR_mseal 462
#define __NR_setxattrat 463
#define __NR_getxattrat 464
#define __NR_listxattrat 465
#define __NR_removexattrat 466
#endif /* __MLIBC_SYSCALLNOS_h */
@@ -0,0 +1,24 @@
.section .text
.global __mlibc_spawn_thread
.type __mlibc_spawn_thread, "function"
/* int (int flags, void *stack, void *pid_out, void *child_tid, void *tcb); */
__mlibc_spawn_thread:
movem.l %d2-%d5, -(%sp)
move.l #120, %d0
movem.l 20(%sp), %d1-%d5
addi.l #0x7048, %d5
trap #0
tst.l %d0
beq 1f
movem.l (%sp)+, %d2-%d5
rts
1:
jbsr __mlibc_enter_thread@PLTPC
illegal
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,170 @@
sysdep_supported_options = {
'posix': true,
'linux': true,
'glibc': true,
'bsd': true,
}
rtld_dso_sources += files(
host_machine.cpu_family() / 'arch-syscall.cpp',
'generic/sysdeps.cpp',
)
linux_include_dirs = [
include_directories(host_machine.cpu_family()),
include_directories('include-internal/'),
]
rtld_include_dirs += linux_include_dirs
libc_include_dirs += linux_include_dirs
libc_sources += files(
host_machine.cpu_family() / 'signals.S',
host_machine.cpu_family() / 'arch-syscall.cpp',
host_machine.cpu_family() / 'assembly-asserts.cpp',
'generic/entry.cpp',
'generic/sysdeps.cpp',
)
if get_option('posix_option').allowed()
libc_sources += files(
'generic/thread.cpp',
host_machine.cpu_family() / 'cp_syscall.S',
host_machine.cpu_family() / 'thread_entry.S'
)
endif
if not no_headers
install_headers(
'include/abi-bits/auxv.h',
'include/abi-bits/seek-whence.h',
'include/abi-bits/vm-flags.h',
'include/abi-bits/errno.h',
'include/abi-bits/fcntl.h',
'include/abi-bits/in.h',
'include/abi-bits/stat.h',
'include/abi-bits/statx.h',
'include/abi-bits/signal.h',
'include/abi-bits/reboot.h',
'include/abi-bits/resource.h',
'include/abi-bits/socket.h',
'include/abi-bits/termios.h',
'include/abi-bits/time.h',
'include/abi-bits/blkcnt_t.h',
'include/abi-bits/blksize_t.h',
'include/abi-bits/dev_t.h',
'include/abi-bits/gid_t.h',
'include/abi-bits/ino_t.h',
'include/abi-bits/mode_t.h',
'include/abi-bits/nlink_t.h',
'include/abi-bits/pid_t.h',
'include/abi-bits/uid_t.h',
'include/abi-bits/access.h',
'include/abi-bits/wait.h',
'include/abi-bits/limits.h',
'include/abi-bits/utsname.h',
'include/abi-bits/ptrace.h',
'include/abi-bits/vt.h',
'include/abi-bits/ptrace.h',
'include/abi-bits/poll.h',
'include/abi-bits/epoll.h',
'include/abi-bits/packet.h',
'include/abi-bits/inotify.h',
'include/abi-bits/clockid_t.h',
'include/abi-bits/ipc.h',
'include/abi-bits/shm.h',
'include/abi-bits/mqueue.h',
'include/abi-bits/suseconds_t.h',
'include/abi-bits/fsfilcnt_t.h',
'include/abi-bits/fsblkcnt_t.h',
'include/abi-bits/socklen_t.h',
'include/abi-bits/statfs.h',
'include/abi-bits/statvfs.h',
'include/abi-bits/ioctls.h',
'include/abi-bits/xattr.h',
'include/abi-bits/msg.h',
'include/abi-bits/random.h',
'include/abi-bits/rlim_t.h',
'include/abi-bits/sigval.h',
'include/abi-bits/sigevent.h',
'include/abi-bits/utmpx.h',
'include/abi-bits/utmp-defines.h',
subdir: 'abi-bits',
follow_symlinks: true
)
if host_machine.cpu_family() == 'riscv64'
install_headers(
'include/abi-bits/riscv-hwprobe.h',
subdir: 'abi-bits',
follow_symlinks: true
)
endif
install_headers('include/syscall.h')
install_headers('include/sys/syscall.h', subdir: 'sys')
install_headers(
'include/bits/syscall.h',
'include/bits/syscall_aliases.h',
subdir: 'bits'
)
endif
if not headers_only
crt = custom_target('crt1',
build_by_default: true,
command: c_compiler.cmd_array() + ['-c', '-o', '@OUTPUT@', '@INPUT@'],
input: host_machine.cpu_family() / 'crt-src/crt1.S',
output: 'crt1.o',
install: true,
install_dir: get_option('libdir')
)
crt_pie = custom_target('Scrt1',
build_by_default: true,
command: c_compiler.cmd_array() + ['-fPIE', '-c', '-o', '@OUTPUT@', '@INPUT@'],
input: host_machine.cpu_family() / 'crt-src/Scrt1.S',
output: 'Scrt1.o',
install: true,
install_dir: get_option('libdir')
)
# On RISC-V and LoongArch, crti.o and crtn.o are provided by GCC.
if host_machine.cpu_family() != 'riscv64' and host_machine.cpu_family() != 'loongarch64'
custom_target('crti',
build_by_default: true,
command: c_compiler.cmd_array() + ['-c', '-o', '@OUTPUT@', '@INPUT@'],
input: host_machine.cpu_family() / 'crt-src/crti.S',
output: 'crti.o',
install: true,
install_dir: get_option('libdir')
)
custom_target('crtn',
build_by_default: true,
command: c_compiler.cmd_array() + ['-c', '-o', '@OUTPUT@', '@INPUT@'],
input: host_machine.cpu_family() / 'crt-src/crtn.S',
output: 'crtn.o',
install: true,
install_dir: get_option('libdir')
)
endif
wrapper_conf = configuration_data()
wrapper_conf.set('LIBDIR', get_option('libdir'))
wrapper_conf.set('PREFIX', get_option('prefix'))
specs = configure_file(input: 'mlibc-gcc.specs.in',
output: 'mlibc-gcc.specs',
configuration: wrapper_conf)
wrapper_script = configure_file(input: 'mlibc-gcc.in',
output: 'mlibc-gcc',
configuration: wrapper_conf)
install_data(specs,
install_dir: get_option('libdir')
)
install_data(wrapper_script,
install_dir: get_option('bindir')
)
endif
+2
View File
@@ -0,0 +1,2 @@
#!/bin/sh
exec "${REALGCC:-gcc}" "$@" -specs "@PREFIX@/@LIBDIR@/mlibc-gcc.specs"
@@ -0,0 +1,32 @@
%rename cpp_options old_cpp_options
*cpp_options:
-nostdinc -isystem @PREFIX@/include -isystem include%s %(old_cpp_options)
*cc1:
%(cc1_cpu) -nostdinc -isystem @PREFIX@/include -isystem include%s
*link_libgcc:
-L@PREFIX@/@LIBDIR@ -L .%s
*libgcc:
libgcc.a%s %:if-exists(libgcc_eh.a%s)
*startfile:
%{!shared: @PREFIX@/@LIBDIR@/Scrt1.o} @PREFIX@/@LIBDIR@/crti.o crtbeginS.o%s
*endfile:
crtendS.o%s @PREFIX@/@LIBDIR@/crtn.o
*link:
-dynamic-linker @PREFIX@/@LIBDIR@/ld.so -rpath @PREFIX@/@LIBDIR@ -nostdlib %{shared:-shared} %{static:-static} %{rdynamic:-export-dynamic}
*esp_link:
*esp_options:
*esp_cpp_options:
@@ -0,0 +1,117 @@
#include <sys/syscall.h>
#include <bits/syscall.h>
using sc_word_t = __sc_word_t;
sc_word_t __do_syscall0(long sc) {
register int sc_reg asm("a7") = sc;
register sc_word_t ret asm("a0");
asm volatile ("ecall" : "=r"(ret) : "r"(sc_reg) : "memory", "a1");
return ret;
}
sc_word_t __do_syscall1(long sc,
sc_word_t arg1) {
register int sc_reg asm("a7") = sc;
register sc_word_t arg1_reg asm("a0") = arg1;
register sc_word_t ret asm("a0");
asm volatile ("ecall" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg)
: "memory", "a1");
return ret;
}
sc_word_t __do_syscall2(long sc,
sc_word_t arg1, sc_word_t arg2) {
register int sc_reg asm("a7") = sc;
register sc_word_t arg1_reg asm("a0") = arg1;
register sc_word_t arg2_reg asm("a1") = arg2;
register sc_word_t ret asm("a0");
asm volatile ("ecall" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg),
"r"(arg2_reg)
: "memory");
return ret;
}
sc_word_t __do_syscall3(long sc,
sc_word_t arg1, sc_word_t arg2, sc_word_t arg3) {
register int sc_reg asm("a7") = sc;
register sc_word_t arg1_reg asm("a0") = arg1;
register sc_word_t arg2_reg asm("a1") = arg2;
register sc_word_t arg3_reg asm("a2") = arg3;
register sc_word_t ret asm("a0");
asm volatile ("ecall" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg),
"r"(arg2_reg),
"r"(arg3_reg)
: "memory");
return ret;
}
sc_word_t __do_syscall4(long sc,
sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4) {
register int sc_reg asm("a7") = sc;
register sc_word_t arg1_reg asm("a0") = arg1;
register sc_word_t arg2_reg asm("a1") = arg2;
register sc_word_t arg3_reg asm("a2") = arg3;
register sc_word_t arg4_reg asm("a3") = arg4;
register sc_word_t ret asm("a0");
asm volatile ("ecall" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg),
"r"(arg2_reg),
"r"(arg3_reg),
"r"(arg4_reg)
: "memory");
return ret;
}
sc_word_t __do_syscall5(long sc,
sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4, sc_word_t arg5) {
register int sc_reg asm("a7") = sc;
register sc_word_t arg1_reg asm("a0") = arg1;
register sc_word_t arg2_reg asm("a1") = arg2;
register sc_word_t arg3_reg asm("a2") = arg3;
register sc_word_t arg4_reg asm("a3") = arg4;
register sc_word_t arg5_reg asm("a4") = arg5;
register sc_word_t ret asm("a0");
asm volatile ("ecall" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg),
"r"(arg2_reg),
"r"(arg3_reg),
"r"(arg4_reg),
"r"(arg5_reg)
: "memory");
return ret;
}
sc_word_t __do_syscall6(long sc,
sc_word_t arg1, sc_word_t arg2, sc_word_t arg3,
sc_word_t arg4, sc_word_t arg5, sc_word_t arg6) {
register int sc_reg asm("a7") = sc;
register sc_word_t arg1_reg asm("a0") = arg1;
register sc_word_t arg2_reg asm("a1") = arg2;
register sc_word_t arg3_reg asm("a2") = arg3;
register sc_word_t arg4_reg asm("a3") = arg4;
register sc_word_t arg5_reg asm("a4") = arg5;
register sc_word_t arg6_reg asm("a5") = arg6;
register sc_word_t ret asm("a0");
asm volatile ("ecall" : "=r"(ret) :
"r"(sc_reg),
"r"(arg1_reg),
"r"(arg2_reg),
"r"(arg3_reg),
"r"(arg4_reg),
"r"(arg5_reg),
"r"(arg6_reg)
: "memory"
);
return ret;
}
@@ -0,0 +1,30 @@
.section .text
.global __mlibc_do_asm_cp_syscall
.global __mlibc_syscall_begin
.global __mlibc_syscall_end
.type __mlibc_do_asm_cp_syscall, "function"
__mlibc_do_asm_cp_syscall:
sd a7, -8(sp)
mv a7, a0
mv a0, a1
mv a1, a2
mv a2, a3
mv a3, a4
mv a4, a5
mv a5, a6
ld a6, -8(sp) // a7
lw t0, -96(tp) // Tcb::cancelBits. See asserts in tcb.hpp.
__mlibc_syscall_begin:
// tcbCancelEnableBit && tcbCancelTriggerBit
li t1, (1 << 0) | (1 << 2)
and t0, t0, t1
beq t0, t1, cancel
ecall
__mlibc_syscall_end:
ret
cancel:
call __mlibc_do_cancel
unimp
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,30 @@
.weak __global_pointer$
.hidden __global_pointer$
.section .text
.global _start
_start:
# Load gp.
.option push
.option norelax
lla gp, __global_pointer$
.option pop
mv a0, sp
la a1, main
call __mlibc_entry@plt
unimp
# Load gp from .preinit_array since it may be used by the executable's .init_array.
# We still load it in _start to account for static binaries. This matches glibc's behavior.
load_gp:
.option push
.option norelax
lla gp, __global_pointer$
.option pop
ret
.section .preinit_array,"aw"
.dword load_gp
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,30 @@
.weak __global_pointer$
.hidden __global_pointer$
.section .text
.global _start
_start:
# Load gp.
.option push
.option norelax
lla gp, __global_pointer$
.option pop
mv a0, sp
la a1, main
call __mlibc_entry
unimp
# Load gp from .preinit_array since it may be used by the executable's .init_array.
# We still load it in _start to account for static binaries. This matches glibc's behavior.
load_gp:
.option push
.option norelax
lla gp, __global_pointer$
.option pop
ret
.section .preinit_array,"aw"
.dword load_gp
.section .note.GNU-stack,"",%progbits
@@ -0,0 +1,12 @@
.section .text
.global __mlibc_signal_restore
.type __mlibc_signal_restore, @function
__mlibc_signal_restore:
.global __mlibc_signal_restore_rt
.type __mlibc_signal_restore_rt, @function
__mlibc_signal_restore_rt:
li a7, 139
ecall
.section .note.GNU-stack,"",%progbits

Some files were not shown because too many files have changed in this diff Show More