authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2021-02-09 22:15:21+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-10 11:50:55-08:00
log6dc2236054dfcf911ce848f67a4078740a90783a
tree37deb296f0fafbc258ea130045e23d224a3f499a
parenta2ec77041bc4a58d922cd3f8db923b7272b1f8f7

musl: update to 1.2.2


188 files changed, 2522 insertions(+), 784 deletions(-)

lib/libc/include/aarch64-linux-musl/bits/alltypes.h+6
......@@ -365,6 +365,12 @@ struct iovec { void *iov_base; size_t iov_len; };
365365#endif
366366
367367
368#if defined(__NEED_struct_winsize) && !defined(__DEFINED_struct_winsize)
369struct winsize { unsigned short ws_row, ws_col, ws_xpixel, ws_ypixel; };
370#define __DEFINED_struct_winsize
371#endif
372
373
368374#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t)
369375typedef unsigned socklen_t;
370376#define __DEFINED_socklen_t
lib/libc/include/aarch64-linux-musl/bits/hwcap.h+11-1
......@@ -37,4 +37,14 @@
3737#define HWCAP2_SVEPMULL (1 << 3)
3838#define HWCAP2_SVEBITPERM (1 << 4)
3939#define HWCAP2_SVESHA3 (1 << 5)
40#define HWCAP2_SVESM4 (1 << 6)
\ No newline at end of file
40#define HWCAP2_SVESM4 (1 << 6)
41#define HWCAP2_FLAGM2 (1 << 7)
42#define HWCAP2_FRINT (1 << 8)
43#define HWCAP2_SVEI8MM (1 << 9)
44#define HWCAP2_SVEF32MM (1 << 10)
45#define HWCAP2_SVEF64MM (1 << 11)
46#define HWCAP2_SVEBF16 (1 << 12)
47#define HWCAP2_I8MM (1 << 13)
48#define HWCAP2_BF16 (1 << 14)
49#define HWCAP2_DGH (1 << 15)
50#define HWCAP2_RNG (1 << 16)
\ No newline at end of file
lib/libc/include/aarch64-linux-musl/bits/signal.h+2-2
......@@ -11,7 +11,7 @@ typedef unsigned long greg_t;
1111typedef unsigned long gregset_t[34];
1212
1313typedef struct {
14 long double vregs[32];
14 __uint128_t vregs[32];
1515 unsigned int fpsr;
1616 unsigned int fpcr;
1717} fpregset_t;
......@@ -34,7 +34,7 @@ struct fpsimd_context {
3434 struct _aarch64_ctx head;
3535 unsigned int fpsr;
3636 unsigned int fpcr;
37 long double vregs[32];
37 __uint128_t vregs[32];
3838};
3939struct esr_context {
4040 struct _aarch64_ctx head;
lib/libc/include/aarch64-linux-musl/bits/syscall.h+9-1
......@@ -289,6 +289,10 @@
289289#define __NR_fspick 433
290290#define __NR_pidfd_open 434
291291#define __NR_clone3 435
292#define __NR_close_range 436
293#define __NR_openat2 437
294#define __NR_pidfd_getfd 438
295#define __NR_faccessat2 439
292296
293297#define SYS_io_setup 0
294298#define SYS_io_destroy 1
......@@ -580,4 +584,8 @@
580584#define SYS_fsmount 432
581585#define SYS_fspick 433
582586#define SYS_pidfd_open 434
583#define SYS_clone3 435
\ No newline at end of file
587#define SYS_clone3 435
588#define SYS_close_range 436
589#define SYS_openat2 437
590#define SYS_pidfd_getfd 438
591#define SYS_faccessat2 439
\ No newline at end of file
lib/libc/include/aarch64-linux-musl/bits/user.h+1-1
......@@ -6,7 +6,7 @@ struct user_regs_struct {
66};
77
88struct user_fpsimd_struct {
9 long double vregs[32];
9 __uint128_t vregs[32];
1010 unsigned int fpsr;
1111 unsigned int fpcr;
1212};
lib/libc/include/arm-linux-musl/bits/alltypes.h+6
......@@ -350,6 +350,12 @@ struct iovec { void *iov_base; size_t iov_len; };
350350#endif
351351
352352
353#if defined(__NEED_struct_winsize) && !defined(__DEFINED_struct_winsize)
354struct winsize { unsigned short ws_row, ws_col, ws_xpixel, ws_ypixel; };
355#define __DEFINED_struct_winsize
356#endif
357
358
353359#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t)
354360typedef unsigned socklen_t;
355361#define __DEFINED_socklen_t
lib/libc/include/arm-linux-musl/bits/syscall.h+9-1
......@@ -389,6 +389,10 @@
389389#define __NR_fspick 433
390390#define __NR_pidfd_open 434
391391#define __NR_clone3 435
392#define __NR_close_range 436
393#define __NR_openat2 437
394#define __NR_pidfd_getfd 438
395#define __NR_faccessat2 439
392396
393397#define __ARM_NR_breakpoint 0x0f0001
394398#define __ARM_NR_cacheflush 0x0f0002
......@@ -787,4 +791,8 @@
787791#define SYS_fsmount 432
788792#define SYS_fspick 433
789793#define SYS_pidfd_open 434
790#define SYS_clone3 435
\ No newline at end of file
794#define SYS_clone3 435
795#define SYS_close_range 436
796#define SYS_openat2 437
797#define SYS_pidfd_getfd 438
798#define SYS_faccessat2 439
\ No newline at end of file
lib/libc/include/generic-musl/bits/fcntl.h created+46
......@@ -0,0 +1,46 @@
1#define O_CREAT 0100
2#define O_EXCL 0200
3#define O_NOCTTY 0400
4#define O_TRUNC 01000
5#define O_APPEND 02000
6#define O_NONBLOCK 04000
7#define O_DSYNC 010000
8#define O_SYNC 04010000
9#define O_RSYNC 04010000
10#define O_DIRECTORY 0200000
11#define O_NOFOLLOW 0400000
12#define O_CLOEXEC 02000000
13
14#define O_ASYNC 020000
15#define O_DIRECT 040000
16#define O_LARGEFILE 0100000
17#define O_NOATIME 01000000
18#define O_PATH 010000000
19#define O_TMPFILE 020200000
20#define O_NDELAY O_NONBLOCK
21
22#define F_DUPFD 0
23#define F_GETFD 1
24#define F_SETFD 2
25#define F_GETFL 3
26#define F_SETFL 4
27
28#define F_SETOWN 8
29#define F_GETOWN 9
30#define F_SETSIG 10
31#define F_GETSIG 11
32
33#if __LONG_MAX == 0x7fffffffL
34#define F_GETLK 12
35#define F_SETLK 13
36#define F_SETLKW 14
37#else
38#define F_GETLK 5
39#define F_SETLK 6
40#define F_SETLKW 7
41#endif
42
43#define F_SETOWN_EX 15
44#define F_GETOWN_EX 16
45
46#define F_GETOWNER_UIDS 17
\ No newline at end of file
lib/libc/include/generic-musl/elf.h+2
......@@ -603,6 +603,7 @@ typedef struct {
603603#define PT_GNU_EH_FRAME 0x6474e550
604604#define PT_GNU_STACK 0x6474e551
605605#define PT_GNU_RELRO 0x6474e552
606#define PT_GNU_PROPERTY 0x6474e553
606607#define PT_LOSUNW 0x6ffffffa
607608#define PT_SUNWBSS 0x6ffffffa
608609#define PT_SUNWSTACK 0x6ffffffb
......@@ -1085,6 +1086,7 @@ typedef struct {
10851086
10861087#define NT_GNU_BUILD_ID 3
10871088#define NT_GNU_GOLD_VERSION 4
1089#define NT_GNU_PROPERTY_TYPE_0 5
10881090
10891091
10901092
lib/libc/include/generic-musl/netinet/if_ether.h+1
......@@ -59,6 +59,7 @@
5959#define ETH_P_PREAUTH 0x88C7
6060#define ETH_P_TIPC 0x88CA
6161#define ETH_P_LLDP 0x88CC
62#define ETH_P_MRP 0x88E3
6263#define ETH_P_MACSEC 0x88E5
6364#define ETH_P_8021AH 0x88E7
6465#define ETH_P_MVRP 0x88F5
lib/libc/include/generic-musl/netinet/in.h+4-1
......@@ -101,8 +101,10 @@ uint16_t ntohs(uint16_t);
101101#define IPPROTO_MH 135
102102#define IPPROTO_UDPLITE 136
103103#define IPPROTO_MPLS 137
104#define IPPROTO_ETHERNET 143
104105#define IPPROTO_RAW 255
105#define IPPROTO_MAX 256
106#define IPPROTO_MPTCP 262
107#define IPPROTO_MAX 263
106108
107109#define IN6_IS_ADDR_UNSPECIFIED(a) \
108110 (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \
......@@ -200,6 +202,7 @@ uint16_t ntohs(uint16_t);
200202#define IP_CHECKSUM 23
201203#define IP_BIND_ADDRESS_NO_PORT 24
202204#define IP_RECVFRAGSIZE 25
205#define IP_RECVERR_RFC4884 26
203206#define IP_MULTICAST_IF 32
204207#define IP_MULTICAST_TTL 33
205208#define IP_MULTICAST_LOOP 34
lib/libc/include/generic-musl/netinet/tcp.h+15-3
......@@ -78,6 +78,8 @@ enum {
7878 TCP_NLA_DSACK_DUPS,
7979 TCP_NLA_REORD_SEEN,
8080 TCP_NLA_SRTT,
81 TCP_NLA_TIMEOUT_REHASH,
82 TCP_NLA_BYTES_NOTSENT,
8183};
8284
8385#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
......@@ -181,6 +183,13 @@ struct tcphdr {
181183#define TCP_CA_Recovery 3
182184#define TCP_CA_Loss 4
183185
186enum tcp_fastopen_client_fail {
187 TFO_STATUS_UNSPEC,
188 TFO_COOKIE_UNAVAILABLE,
189 TFO_DATA_NOT_ACKED,
190 TFO_SYN_RETRANSMITTED,
191};
192
184193struct tcp_info {
185194 uint8_t tcpi_state;
186195 uint8_t tcpi_ca_state;
......@@ -189,7 +198,7 @@ struct tcp_info {
189198 uint8_t tcpi_backoff;
190199 uint8_t tcpi_options;
191200 uint8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
192 uint8_t tcpi_delivery_rate_app_limited : 1;
201 uint8_t tcpi_delivery_rate_app_limited : 1, tcpi_fastopen_client_fail : 2;
193202 uint32_t tcpi_rto;
194203 uint32_t tcpi_ato;
195204 uint32_t tcpi_snd_mss;
......@@ -240,14 +249,15 @@ struct tcp_info {
240249
241250#define TCP_MD5SIG_MAXKEYLEN 80
242251
243#define TCP_MD5SIG_FLAG_PREFIX 1
252#define TCP_MD5SIG_FLAG_PREFIX 0x1
253#define TCP_MD5SIG_FLAG_IFINDEX 0x2
244254
245255struct tcp_md5sig {
246256 struct sockaddr_storage tcpm_addr;
247257 uint8_t tcpm_flags;
248258 uint8_t tcpm_prefixlen;
249259 uint16_t tcpm_keylen;
250 uint32_t __tcpm_pad;
260 int tcpm_ifindex;
251261 uint8_t tcpm_key[TCP_MD5SIG_MAXKEYLEN];
252262};
253263
......@@ -275,6 +285,8 @@ struct tcp_zerocopy_receive {
275285 uint64_t address;
276286 uint32_t length;
277287 uint32_t recv_skip_hint;
288 uint32_t inq;
289 int32_t err;
278290};
279291
280292#endif
lib/libc/include/generic-musl/netinet/udp.h+1
......@@ -35,6 +35,7 @@ struct udphdr {
3535#define UDP_ENCAP_GTP0 4
3636#define UDP_ENCAP_GTP1U 5
3737#define UDP_ENCAP_RXRPC 6
38#define TCP_ENCAP_ESPINTCP 7
3839
3940#define SOL_UDP 17
4041
lib/libc/include/generic-musl/sched.h+1
......@@ -49,6 +49,7 @@ int sched_yield(void);
4949
5050#ifdef _GNU_SOURCE
5151#define CSIGNAL 0x000000ff
52#define CLONE_NEWTIME 0x00000080
5253#define CLONE_VM 0x00000100
5354#define CLONE_FS 0x00000200
5455#define CLONE_FILES 0x00000400
lib/libc/include/generic-musl/signal.h+13-3
......@@ -180,14 +180,24 @@ struct sigevent {
180180 union sigval sigev_value;
181181 int sigev_signo;
182182 int sigev_notify;
183 void (*sigev_notify_function)(union sigval);
184 pthread_attr_t *sigev_notify_attributes;
185 char __pad[56-3*sizeof(long)];
183 union {
184 char __pad[64 - 2*sizeof(int) - sizeof(union sigval)];
185 pid_t sigev_notify_thread_id;
186 struct {
187 void (*sigev_notify_function)(union sigval);
188 pthread_attr_t *sigev_notify_attributes;
189 } __sev_thread;
190 } __sev_fields;
186191};
187192
193#define sigev_notify_thread_id __sev_fields.sigev_notify_thread_id
194#define sigev_notify_function __sev_fields.__sev_thread.sigev_notify_function
195#define sigev_notify_attributes __sev_fields.__sev_thread.sigev_notify_attributes
196
188197#define SIGEV_SIGNAL 0
189198#define SIGEV_NONE 1
190199#define SIGEV_THREAD 2
200#define SIGEV_THREAD_ID 4
191201
192202int __libc_current_sigrtmin(void);
193203int __libc_current_sigrtmax(void);
lib/libc/include/generic-musl/stdlib.h+1
......@@ -145,6 +145,7 @@ int getloadavg(double *, int);
145145int clearenv(void);
146146#define WCOREDUMP(s) ((s) & 0x80)
147147#define WIFCONTINUED(s) ((s) == 0xffff)
148void *reallocarray (void *, size_t, size_t);
148149#endif
149150
150151#ifdef _GNU_SOURCE
lib/libc/include/generic-musl/sys/fanotify.h+7-1
......@@ -55,8 +55,9 @@ struct fanotify_response {
5555#define FAN_OPEN_PERM 0x10000
5656#define FAN_ACCESS_PERM 0x20000
5757#define FAN_OPEN_EXEC_PERM 0x40000
58#define FAN_ONDIR 0x40000000
58#define FAN_DIR_MODIFY 0x00080000
5959#define FAN_EVENT_ON_CHILD 0x08000000
60#define FAN_ONDIR 0x40000000
6061#define FAN_CLOSE (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE)
6162#define FAN_MOVE (FAN_MOVED_FROM | FAN_MOVED_TO)
6263#define FAN_CLOEXEC 0x01
......@@ -70,6 +71,9 @@ struct fanotify_response {
7071#define FAN_ENABLE_AUDIT 0x40
7172#define FAN_REPORT_TID 0x100
7273#define FAN_REPORT_FID 0x200
74#define FAN_REPORT_DIR_FID 0x00000400
75#define FAN_REPORT_NAME 0x00000800
76#define FAN_REPORT_DFID_NAME (FAN_REPORT_DIR_FID | FAN_REPORT_NAME)
7377#define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK | FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE | FAN_UNLIMITED_MARKS)
7478#define FAN_MARK_ADD 0x01
7579#define FAN_MARK_REMOVE 0x02
......@@ -88,6 +92,8 @@ struct fanotify_response {
8892#define FAN_ALL_OUTGOING_EVENTS (FAN_ALL_EVENTS | FAN_ALL_PERM_EVENTS | FAN_Q_OVERFLOW)
8993#define FANOTIFY_METADATA_VERSION 3
9094#define FAN_EVENT_INFO_TYPE_FID 1
95#define FAN_EVENT_INFO_TYPE_DFID_NAME 2
96#define FAN_EVENT_INFO_TYPE_DFID 3
9197#define FAN_ALLOW 0x01
9298#define FAN_DENY 0x02
9399#define FAN_AUDIT 0x10
lib/libc/include/generic-musl/sys/ioctl.h+2-7
......@@ -4,6 +4,8 @@
44extern "C" {
55#endif
66
7#define __NEED_struct_winsize
8
79#include <bits/alltypes.h>
810#include <bits/ioctl.h>
911
......@@ -47,13 +49,6 @@ extern "C" {
4749
4850#define TIOCSER_TEMT 1
4951
50struct winsize {
51 unsigned short ws_row;
52 unsigned short ws_col;
53 unsigned short ws_xpixel;
54 unsigned short ws_ypixel;
55};
56
5752#define SIOCADDRT 0x890B
5853#define SIOCDELRT 0x890C
5954#define SIOCRTMSG 0x890D
lib/libc/include/generic-musl/sys/mman.h+1
......@@ -101,6 +101,7 @@ extern "C" {
101101#ifdef _GNU_SOURCE
102102#define MREMAP_MAYMOVE 1
103103#define MREMAP_FIXED 2
104#define MREMAP_DONTUNMAP 4
104105
105106#define MLOCK_ONFAULT 0x01
106107
lib/libc/include/generic-musl/sys/personality.h+3
......@@ -5,7 +5,9 @@
55extern "C" {
66#endif
77
8#define UNAME26 0x0020000
89#define ADDR_NO_RANDOMIZE 0x0040000
10#define FDPIC_FUNCPTRS 0x0080000
911#define MMAP_PAGE_ZERO 0x0100000
1012#define ADDR_COMPAT_LAYOUT 0x0200000
1113#define READ_IMPLIES_EXEC 0x0400000
......@@ -17,6 +19,7 @@ extern "C" {
1719
1820#define PER_LINUX 0
1921#define PER_LINUX_32BIT ADDR_LIMIT_32BIT
22#define PER_LINUX_FDPIC FDPIC_FUNCPTRS
2023#define PER_SVR4 (1 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO)
2124#define PER_SVR3 (2 | STICKY_TIMEOUTS | SHORT_INODE)
2225#define PER_SCOSVR3 (3 | STICKY_TIMEOUTS | WHOLE_SECONDS | SHORT_INODE)
lib/libc/include/generic-musl/sys/prctl.h+3
......@@ -158,6 +158,9 @@ struct prctl_mm_map {
158158#define PR_GET_TAGGED_ADDR_CTRL 56
159159#define PR_TAGGED_ADDR_ENABLE (1UL << 0)
160160
161#define PR_SET_IO_FLUSHER 57
162#define PR_GET_IO_FLUSHER 58
163
161164int prctl (int, ...);
162165
163166#ifdef __cplusplus
lib/libc/include/generic-musl/sys/random.h+1
......@@ -10,6 +10,7 @@ extern "C" {
1010
1111#define GRND_NONBLOCK 0x0001
1212#define GRND_RANDOM 0x0002
13#define GRND_INSECURE 0x0004
1314
1415ssize_t getrandom(void *, size_t, unsigned);
1516
lib/libc/include/generic-musl/termios.h+4
......@@ -8,6 +8,7 @@ extern "C" {
88#include <features.h>
99
1010#define __NEED_pid_t
11#define __NEED_struct_winsize
1112
1213#include <bits/alltypes.h>
1314
......@@ -27,6 +28,9 @@ int cfsetispeed (struct termios *, speed_t);
2728int tcgetattr (int, struct termios *);
2829int tcsetattr (int, int, const struct termios *);
2930
31int tcgetwinsize (int, struct winsize *);
32int tcsetwinsize (int, const struct winsize *);
33
3034int tcsendbreak (int, int);
3135int tcdrain (int);
3236int tcflush (int, int);
lib/libc/include/generic-musl/unistd.h+2
......@@ -82,6 +82,7 @@ unsigned sleep(unsigned);
8282int pause(void);
8383
8484pid_t fork(void);
85pid_t _Fork(void);
8586int execve(const char *, char *const [], char *const []);
8687int execv(const char *, char *const []);
8788int execle(const char *, const char *, ...);
......@@ -190,6 +191,7 @@ int syncfs(int);
190191int euidaccess(const char *, int);
191192int eaccess(const char *, int);
192193ssize_t copy_file_range(int, off_t *, int, off_t *, size_t, unsigned);
194pid_t gettid(void);
193195#endif
194196
195197#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
lib/libc/include/i386-linux-musl/bits/alltypes.h+6
......@@ -380,6 +380,12 @@ struct iovec { void *iov_base; size_t iov_len; };
380380#endif
381381
382382
383#if defined(__NEED_struct_winsize) && !defined(__DEFINED_struct_winsize)
384struct winsize { unsigned short ws_row, ws_col, ws_xpixel, ws_ypixel; };
385#define __DEFINED_struct_winsize
386#endif
387
388
383389#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t)
384390typedef unsigned socklen_t;
385391#define __DEFINED_socklen_t
lib/libc/include/i386-linux-musl/bits/syscall.h+9-1
......@@ -426,6 +426,10 @@
426426#define __NR_fspick 433
427427#define __NR_pidfd_open 434
428428#define __NR_clone3 435
429#define __NR_close_range 436
430#define __NR_openat2 437
431#define __NR_pidfd_getfd 438
432#define __NR_faccessat2 439
429433
430434#define SYS_restart_syscall 0
431435#define SYS_exit 1
......@@ -852,4 +856,8 @@
852856#define SYS_fsmount 432
853857#define SYS_fspick 433
854858#define SYS_pidfd_open 434
855#define SYS_clone3 435
\ No newline at end of file
859#define SYS_clone3 435
860#define SYS_close_range 436
861#define SYS_openat2 437
862#define SYS_pidfd_getfd 438
863#define SYS_faccessat2 439
\ No newline at end of file
lib/libc/include/mips-linux-musl/bits/alltypes.h+6
......@@ -350,6 +350,12 @@ struct iovec { void *iov_base; size_t iov_len; };
350350#endif
351351
352352
353#if defined(__NEED_struct_winsize) && !defined(__DEFINED_struct_winsize)
354struct winsize { unsigned short ws_row, ws_col, ws_xpixel, ws_ypixel; };
355#define __DEFINED_struct_winsize
356#endif
357
358
353359#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t)
354360typedef unsigned socklen_t;
355361#define __DEFINED_socklen_t
lib/libc/include/mips-linux-musl/bits/syscall.h+9-1
......@@ -408,6 +408,10 @@
408408#define __NR_fspick 4433
409409#define __NR_pidfd_open 4434
410410#define __NR_clone3 4435
411#define __NR_close_range 4436
412#define __NR_openat2 4437
413#define __NR_pidfd_getfd 4438
414#define __NR_faccessat2 4439
411415
412416#define SYS_syscall 4000
413417#define SYS_exit 4001
......@@ -818,4 +822,8 @@
818822#define SYS_fsmount 4432
819823#define SYS_fspick 4433
820824#define SYS_pidfd_open 4434
821#define SYS_clone3 4435
\ No newline at end of file
825#define SYS_clone3 4435
826#define SYS_close_range 4436
827#define SYS_openat2 4437
828#define SYS_pidfd_getfd 4438
829#define SYS_faccessat2 4439
\ No newline at end of file
lib/libc/include/mips64-linux-musl/bits/alltypes.h+6
......@@ -355,6 +355,12 @@ struct iovec { void *iov_base; size_t iov_len; };
355355#endif
356356
357357
358#if defined(__NEED_struct_winsize) && !defined(__DEFINED_struct_winsize)
359struct winsize { unsigned short ws_row, ws_col, ws_xpixel, ws_ypixel; };
360#define __DEFINED_struct_winsize
361#endif
362
363
358364#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t)
359365typedef unsigned socklen_t;
360366#define __DEFINED_socklen_t
lib/libc/include/mips64-linux-musl/bits/fcntl.h+1-1
......@@ -13,7 +13,7 @@
1313
1414#define O_ASYNC 010000
1515#define O_DIRECT 0100000
16#define O_LARGEFILE 0
16#define O_LARGEFILE 020000
1717#define O_NOATIME 01000000
1818#define O_PATH 010000000
1919#define O_TMPFILE 020200000
lib/libc/include/mips64-linux-musl/bits/syscall.h+9-1
......@@ -338,6 +338,10 @@
338338#define __NR_fspick 5433
339339#define __NR_pidfd_open 5434
340340#define __NR_clone3 5435
341#define __NR_close_range 5436
342#define __NR_openat2 5437
343#define __NR_pidfd_getfd 5438
344#define __NR_faccessat2 5439
341345
342346#define SYS_read 5000
343347#define SYS_write 5001
......@@ -678,4 +682,8 @@
678682#define SYS_fsmount 5432
679683#define SYS_fspick 5433
680684#define SYS_pidfd_open 5434
681#define SYS_clone3 5435
\ No newline at end of file
685#define SYS_clone3 5435
686#define SYS_close_range 5436
687#define SYS_openat2 5437
688#define SYS_pidfd_getfd 5438
689#define SYS_faccessat2 5439
\ No newline at end of file
lib/libc/include/powerpc-linux-musl/bits/alltypes.h+6
......@@ -353,6 +353,12 @@ struct iovec { void *iov_base; size_t iov_len; };
353353#endif
354354
355355
356#if defined(__NEED_struct_winsize) && !defined(__DEFINED_struct_winsize)
357struct winsize { unsigned short ws_row, ws_col, ws_xpixel, ws_ypixel; };
358#define __DEFINED_struct_winsize
359#endif
360
361
356362#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t)
357363typedef unsigned socklen_t;
358364#define __DEFINED_socklen_t
lib/libc/include/powerpc-linux-musl/bits/syscall.h+9-1
......@@ -415,6 +415,10 @@
415415#define __NR_fspick 433
416416#define __NR_pidfd_open 434
417417#define __NR_clone3 435
418#define __NR_close_range 436
419#define __NR_openat2 437
420#define __NR_pidfd_getfd 438
421#define __NR_faccessat2 439
418422
419423#define SYS_restart_syscall 0
420424#define SYS_exit 1
......@@ -832,4 +836,8 @@
832836#define SYS_fsmount 432
833837#define SYS_fspick 433
834838#define SYS_pidfd_open 434
835#define SYS_clone3 435
\ No newline at end of file
839#define SYS_clone3 435
840#define SYS_close_range 436
841#define SYS_openat2 437
842#define SYS_pidfd_getfd 438
843#define SYS_faccessat2 439
\ No newline at end of file
lib/libc/include/powerpc64-linux-musl/bits/alltypes.h+6
......@@ -349,6 +349,12 @@ struct iovec { void *iov_base; size_t iov_len; };
349349#endif
350350
351351
352#if defined(__NEED_struct_winsize) && !defined(__DEFINED_struct_winsize)
353struct winsize { unsigned short ws_row, ws_col, ws_xpixel, ws_ypixel; };
354#define __DEFINED_struct_winsize
355#endif
356
357
352358#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t)
353359typedef unsigned socklen_t;
354360#define __DEFINED_socklen_t
lib/libc/include/powerpc64-linux-musl/bits/syscall.h+9-1
......@@ -387,6 +387,10 @@
387387#define __NR_fspick 433
388388#define __NR_pidfd_open 434
389389#define __NR_clone3 435
390#define __NR_close_range 436
391#define __NR_openat2 437
392#define __NR_pidfd_getfd 438
393#define __NR_faccessat2 439
390394
391395#define SYS_restart_syscall 0
392396#define SYS_exit 1
......@@ -776,4 +780,8 @@
776780#define SYS_fsmount 432
777781#define SYS_fspick 433
778782#define SYS_pidfd_open 434
779#define SYS_clone3 435
\ No newline at end of file
783#define SYS_clone3 435
784#define SYS_close_range 436
785#define SYS_openat2 437
786#define SYS_pidfd_getfd 438
787#define SYS_faccessat2 439
\ No newline at end of file
lib/libc/include/riscv64-linux-musl/bits/alltypes.h+6
......@@ -355,6 +355,12 @@ struct iovec { void *iov_base; size_t iov_len; };
355355#endif
356356
357357
358#if defined(__NEED_struct_winsize) && !defined(__DEFINED_struct_winsize)
359struct winsize { unsigned short ws_row, ws_col, ws_xpixel, ws_ypixel; };
360#define __DEFINED_struct_winsize
361#endif
362
363
358364#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t)
359365typedef unsigned socklen_t;
360366#define __DEFINED_socklen_t
lib/libc/include/riscv64-linux-musl/bits/signal.h+2-2
......@@ -60,10 +60,10 @@ struct sigaltstack {
6060 size_t ss_size;
6161};
6262
63typedef struct ucontext_t
63typedef struct __ucontext
6464{
6565 unsigned long uc_flags;
66 struct ucontext_t *uc_link;
66 struct __ucontext *uc_link;
6767 stack_t uc_stack;
6868 sigset_t uc_sigmask;
6969 mcontext_t uc_mcontext;
lib/libc/include/riscv64-linux-musl/bits/syscall.h+8
......@@ -289,6 +289,10 @@
289289#define __NR_fspick 433
290290#define __NR_pidfd_open 434
291291#define __NR_clone3 435
292#define __NR_close_range 436
293#define __NR_openat2 437
294#define __NR_pidfd_getfd 438
295#define __NR_faccessat2 439
292296
293297#define __NR_sysriscv __NR_arch_specific_syscall
294298#define __NR_riscv_flush_icache (__NR_sysriscv + 15)
......@@ -583,5 +587,9 @@
583587#define SYS_fspick 433
584588#define SYS_pidfd_open 434
585589#define SYS_clone3 435
590#define SYS_close_range 436
591#define SYS_openat2 437
592#define SYS_pidfd_getfd 438
593#define SYS_faccessat2 439
586594#define SYS_sysriscv __NR_arch_specific_syscall
587595#define SYS_riscv_flush_icache (__NR_sysriscv + 15)
\ No newline at end of file
lib/libc/include/s390x-linux-musl/bits/alltypes.h+14
......@@ -13,11 +13,19 @@ typedef int wchar_t;
1313
1414#endif
1515
16#if defined(__FLT_EVAL_METHOD__) && __FLT_EVAL_METHOD__ == 1
1617#if defined(__NEED_float_t) && !defined(__DEFINED_float_t)
1718typedef double float_t;
1819#define __DEFINED_float_t
1920#endif
2021
22#else
23#if defined(__NEED_float_t) && !defined(__DEFINED_float_t)
24typedef float float_t;
25#define __DEFINED_float_t
26#endif
27
28#endif
2129#if defined(__NEED_double_t) && !defined(__DEFINED_double_t)
2230typedef double double_t;
2331#define __DEFINED_double_t
......@@ -344,6 +352,12 @@ struct iovec { void *iov_base; size_t iov_len; };
344352#endif
345353
346354
355#if defined(__NEED_struct_winsize) && !defined(__DEFINED_struct_winsize)
356struct winsize { unsigned short ws_row, ws_col, ws_xpixel, ws_ypixel; };
357#define __DEFINED_struct_winsize
358#endif
359
360
347361#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t)
348362typedef unsigned socklen_t;
349363#define __DEFINED_socklen_t
lib/libc/include/s390x-linux-musl/bits/float.h+5-1
......@@ -1,4 +1,8 @@
1#define FLT_EVAL_METHOD 1
1#ifdef __FLT_EVAL_METHOD__
2#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
3#else
4#define FLT_EVAL_METHOD 0
5#endif
26
37#define LDBL_TRUE_MIN 6.47517511943802511092443895822764655e-4966L
48#define LDBL_MIN 3.36210314311209350626267781732175260e-4932L
lib/libc/include/s390x-linux-musl/bits/syscall.h+9-1
......@@ -352,6 +352,10 @@
352352#define __NR_fspick 433
353353#define __NR_pidfd_open 434
354354#define __NR_clone3 435
355#define __NR_close_range 436
356#define __NR_openat2 437
357#define __NR_pidfd_getfd 438
358#define __NR_faccessat2 439
355359
356360#define SYS_exit 1
357361#define SYS_fork 2
......@@ -706,4 +710,8 @@
706710#define SYS_fsmount 432
707711#define SYS_fspick 433
708712#define SYS_pidfd_open 434
709#define SYS_clone3 435
\ No newline at end of file
713#define SYS_clone3 435
714#define SYS_close_range 436
715#define SYS_openat2 437
716#define SYS_pidfd_getfd 438
717#define SYS_faccessat2 439
\ No newline at end of file
lib/libc/include/x86_64-linux-musl/bits/alltypes.h+6
......@@ -357,6 +357,12 @@ struct iovec { void *iov_base; size_t iov_len; };
357357#endif
358358
359359
360#if defined(__NEED_struct_winsize) && !defined(__DEFINED_struct_winsize)
361struct winsize { unsigned short ws_row, ws_col, ws_xpixel, ws_ypixel; };
362#define __DEFINED_struct_winsize
363#endif
364
365
360366#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t)
361367typedef unsigned socklen_t;
362368#define __DEFINED_socklen_t
lib/libc/include/x86_64-linux-musl/bits/syscall.h+9-1
......@@ -345,6 +345,10 @@
345345#define __NR_fspick 433
346346#define __NR_pidfd_open 434
347347#define __NR_clone3 435
348#define __NR_close_range 436
349#define __NR_openat2 437
350#define __NR_pidfd_getfd 438
351#define __NR_faccessat2 439
348352
349353#define SYS_read 0
350354#define SYS_write 1
......@@ -692,4 +696,8 @@
692696#define SYS_fsmount 432
693697#define SYS_fspick 433
694698#define SYS_pidfd_open 434
695#define SYS_clone3 435
\ No newline at end of file
699#define SYS_clone3 435
700#define SYS_close_range 436
701#define SYS_openat2 437
702#define SYS_pidfd_getfd 438
703#define SYS_faccessat2 439
\ No newline at end of file
lib/libc/musl/arch/aarch64/bits/hwcap.h+10
......@@ -38,3 +38,13 @@
3838#define HWCAP2_SVEBITPERM (1 << 4)
3939#define HWCAP2_SVESHA3 (1 << 5)
4040#define HWCAP2_SVESM4 (1 << 6)
41#define HWCAP2_FLAGM2 (1 << 7)
42#define HWCAP2_FRINT (1 << 8)
43#define HWCAP2_SVEI8MM (1 << 9)
44#define HWCAP2_SVEF32MM (1 << 10)
45#define HWCAP2_SVEF64MM (1 << 11)
46#define HWCAP2_SVEBF16 (1 << 12)
47#define HWCAP2_I8MM (1 << 13)
48#define HWCAP2_BF16 (1 << 14)
49#define HWCAP2_DGH (1 << 15)
50#define HWCAP2_RNG (1 << 16)
lib/libc/musl/arch/aarch64/bits/signal.h+2-2
......@@ -11,7 +11,7 @@ typedef unsigned long greg_t;
1111typedef unsigned long gregset_t[34];
1212
1313typedef struct {
14 long double vregs[32];
14 __uint128_t vregs[32];
1515 unsigned int fpsr;
1616 unsigned int fpcr;
1717} fpregset_t;
......@@ -34,7 +34,7 @@ struct fpsimd_context {
3434 struct _aarch64_ctx head;
3535 unsigned int fpsr;
3636 unsigned int fpcr;
37 long double vregs[32];
37 __uint128_t vregs[32];
3838};
3939struct esr_context {
4040 struct _aarch64_ctx head;
lib/libc/musl/arch/aarch64/bits/syscall.h.in+4
......@@ -289,4 +289,8 @@
289289#define __NR_fspick 433
290290#define __NR_pidfd_open 434
291291#define __NR_clone3 435
292#define __NR_close_range 436
293#define __NR_openat2 437
294#define __NR_pidfd_getfd 438
295#define __NR_faccessat2 439
292296
lib/libc/musl/arch/aarch64/bits/user.h+1-1
......@@ -6,7 +6,7 @@ struct user_regs_struct {
66};
77
88struct user_fpsimd_struct {
9 long double vregs[32];
9 __uint128_t vregs[32];
1010 unsigned int fpsr;
1111 unsigned int fpcr;
1212};
lib/libc/musl/arch/aarch64/pthread_arch.h+4-5
......@@ -1,12 +1,11 @@
1static inline struct pthread *__pthread_self()
1static inline uintptr_t __get_tp()
22{
3 char *self;
4 __asm__ ("mrs %0,tpidr_el0" : "=r"(self));
5 return (void*)(self - sizeof(struct pthread));
3 uintptr_t tp;
4 __asm__ ("mrs %0,tpidr_el0" : "=r"(tp));
5 return tp;
66}
77
88#define TLS_ABOVE_TP
99#define GAP_ABOVE_TP 16
10#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread))
1110
1211#define MC_PC pc
lib/libc/musl/arch/arm/bits/syscall.h.in+4
......@@ -389,6 +389,10 @@
389389#define __NR_fspick 433
390390#define __NR_pidfd_open 434
391391#define __NR_clone3 435
392#define __NR_close_range 436
393#define __NR_openat2 437
394#define __NR_pidfd_getfd 438
395#define __NR_faccessat2 439
392396
393397#define __ARM_NR_breakpoint 0x0f0001
394398#define __ARM_NR_cacheflush 0x0f0002
lib/libc/musl/arch/arm/pthread_arch.h+8-9
......@@ -1,11 +1,11 @@
11#if ((__ARM_ARCH_6K__ || __ARM_ARCH_6KZ__ || __ARM_ARCH_6ZK__) && !__thumb__) \
22 || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
33
4static inline pthread_t __pthread_self()
4static inline uintptr_t __get_tp()
55{
6 char *p;
7 __asm__ ( "mrc p15,0,%0,c13,c0,3" : "=r"(p) );
8 return (void *)(p-sizeof(struct pthread));
6 uintptr_t tp;
7 __asm__ ( "mrc p15,0,%0,c13,c0,3" : "=r"(tp) );
8 return tp;
99}
1010
1111#else
......@@ -16,18 +16,17 @@ static inline pthread_t __pthread_self()
1616#define BLX "blx"
1717#endif
1818
19static inline pthread_t __pthread_self()
19static inline uintptr_t __get_tp()
2020{
2121 extern hidden uintptr_t __a_gettp_ptr;
22 register uintptr_t p __asm__("r0");
23 __asm__ ( BLX " %1" : "=r"(p) : "r"(__a_gettp_ptr) : "cc", "lr" );
24 return (void *)(p-sizeof(struct pthread));
22 register uintptr_t tp __asm__("r0");
23 __asm__ ( BLX " %1" : "=r"(tp) : "r"(__a_gettp_ptr) : "cc", "lr" );
24 return tp;
2525}
2626
2727#endif
2828
2929#define TLS_ABOVE_TP
3030#define GAP_ABOVE_TP 8
31#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread))
3231
3332#define MC_PC arm_pc
lib/libc/musl/arch/generic/bits/fcntl.h+6
......@@ -30,9 +30,15 @@
3030#define F_SETSIG 10
3131#define F_GETSIG 11
3232
33#if __LONG_MAX == 0x7fffffffL
3334#define F_GETLK 12
3435#define F_SETLK 13
3536#define F_SETLKW 14
37#else
38#define F_GETLK 5
39#define F_SETLK 6
40#define F_SETLKW 7
41#endif
3642
3743#define F_SETOWN_EX 15
3844#define F_GETOWN_EX 16
lib/libc/musl/arch/i386/bits/syscall.h.in+4
......@@ -426,4 +426,8 @@
426426#define __NR_fspick 433
427427#define __NR_pidfd_open 434
428428#define __NR_clone3 435
429#define __NR_close_range 436
430#define __NR_openat2 437
431#define __NR_pidfd_getfd 438
432#define __NR_faccessat2 439
429433
lib/libc/musl/arch/i386/pthread_arch.h+4-6
......@@ -1,10 +1,8 @@
1static inline struct pthread *__pthread_self()
1static inline uintptr_t __get_tp()
22{
3 struct pthread *self;
4 __asm__ ("movl %%gs:0,%0" : "=r" (self) );
5 return self;
3 uintptr_t tp;
4 __asm__ ("movl %%gs:0,%0" : "=r" (tp) );
5 return tp;
66}
77
8#define TP_ADJ(p) (p)
9
108#define MC_PC gregs[REG_EIP]
lib/libc/musl/arch/i386/syscall_arch.h-2
......@@ -87,5 +87,3 @@ static inline long __syscall6(long n, long a1, long a2, long a3, long a4, long a
8787#define VDSO_CGT32_VER "LINUX_2.6"
8888#define VDSO_CGT_SYM "__vdso_clock_gettime64"
8989#define VDSO_CGT_VER "LINUX_2.6"
90
91#define SYSCALL_USE_SOCKETCALL
lib/libc/musl/arch/mips/bits/syscall.h.in+4
......@@ -408,4 +408,8 @@
408408#define __NR_fspick 4433
409409#define __NR_pidfd_open 4434
410410#define __NR_clone3 4435
411#define __NR_close_range 4436
412#define __NR_openat2 4437
413#define __NR_pidfd_getfd 4438
414#define __NR_faccessat2 4439
411415
lib/libc/musl/arch/mips/pthread_arch.h+5-5
......@@ -1,19 +1,19 @@
1static inline struct pthread *__pthread_self()
1static inline uintptr_t __get_tp()
22{
33#if __mips_isa_rev < 2
4 register char *tp __asm__("$3");
4 register uintptr_t tp __asm__("$3");
55 __asm__ (".word 0x7c03e83b" : "=r" (tp) );
66#else
7 char *tp;
7 uintptr_t tp;
88 __asm__ ("rdhwr %0, $29" : "=r" (tp) );
99#endif
10 return (pthread_t)(tp - 0x7000 - sizeof(struct pthread));
10 return tp;
1111}
1212
1313#define TLS_ABOVE_TP
1414#define GAP_ABOVE_TP 0
15#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
1615
16#define TP_OFFSET 0x7000
1717#define DTP_OFFSET 0x8000
1818
1919#define MC_PC pc
lib/libc/musl/arch/mips/syscall_arch.h+2
......@@ -149,3 +149,5 @@ static inline long __syscall7(long n, long a, long b, long c, long d, long e, lo
149149
150150#define SO_SNDTIMEO_OLD 0x1005
151151#define SO_RCVTIMEO_OLD 0x1006
152
153#undef SYS_socketcall
lib/libc/musl/arch/mips64/bits/fcntl.h+1-1
......@@ -13,7 +13,7 @@
1313
1414#define O_ASYNC 010000
1515#define O_DIRECT 0100000
16#define O_LARGEFILE 0
16#define O_LARGEFILE 020000
1717#define O_NOATIME 01000000
1818#define O_PATH 010000000
1919#define O_TMPFILE 020200000
lib/libc/musl/arch/mips64/bits/syscall.h.in+4
......@@ -338,4 +338,8 @@
338338#define __NR_fspick 5433
339339#define __NR_pidfd_open 5434
340340#define __NR_clone3 5435
341#define __NR_close_range 5436
342#define __NR_openat2 5437
343#define __NR_pidfd_getfd 5438
344#define __NR_faccessat2 5439
341345
lib/libc/musl/arch/mips64/pthread_arch.h+5-5
......@@ -1,19 +1,19 @@
1static inline struct pthread *__pthread_self()
1static inline uintptr_t __get_tp()
22{
33#if __mips_isa_rev < 2
4 register char *tp __asm__("$3");
4 register uintptr_t tp __asm__("$3");
55 __asm__ (".word 0x7c03e83b" : "=r" (tp) );
66#else
7 char *tp;
7 uintptr_t tp;
88 __asm__ ("rdhwr %0, $29" : "=r" (tp) );
99#endif
10 return (pthread_t)(tp - 0x7000 - sizeof(struct pthread));
10 return tp;
1111}
1212
1313#define TLS_ABOVE_TP
1414#define GAP_ABOVE_TP 0
15#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
1615
16#define TP_OFFSET 0x7000
1717#define DTP_OFFSET 0x8000
1818
1919#define MC_PC pc
lib/libc/musl/arch/powerpc/bits/syscall.h.in+4
......@@ -415,4 +415,8 @@
415415#define __NR_fspick 433
416416#define __NR_pidfd_open 434
417417#define __NR_clone3 435
418#define __NR_close_range 436
419#define __NR_openat2 437
420#define __NR_pidfd_getfd 438
421#define __NR_faccessat2 439
418422
lib/libc/musl/arch/powerpc/pthread_arch.h+4-6
......@@ -1,18 +1,16 @@
1static inline struct pthread *__pthread_self()
1static inline uintptr_t __get_tp()
22{
3 register char *tp __asm__("r2");
3 register uintptr_t tp __asm__("r2");
44 __asm__ ("" : "=r" (tp) );
5 return (pthread_t)(tp - 0x7000 - sizeof(struct pthread));
5 return tp;
66}
77
88#define TLS_ABOVE_TP
99#define GAP_ABOVE_TP 0
10#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
1110
11#define TP_OFFSET 0x7000
1212#define DTP_OFFSET 0x8000
1313
1414// the kernel calls the ip "nip", it's the first saved value after the 32
1515// GPRs.
1616#define MC_PC gregs[32]
17
18#define CANARY canary_at_end
lib/libc/musl/arch/powerpc64/bits/syscall.h.in+4
......@@ -387,4 +387,8 @@
387387#define __NR_fspick 433
388388#define __NR_pidfd_open 434
389389#define __NR_clone3 435
390#define __NR_close_range 436
391#define __NR_openat2 437
392#define __NR_pidfd_getfd 438
393#define __NR_faccessat2 439
390394
lib/libc/musl/arch/powerpc64/pthread_arch.h+4-6
......@@ -1,18 +1,16 @@
1static inline struct pthread *__pthread_self()
1static inline uintptr_t __get_tp()
22{
3 register char *tp __asm__("r13");
3 register uintptr_t tp __asm__("r13");
44 __asm__ ("" : "=r" (tp) );
5 return (pthread_t)(tp - 0x7000 - sizeof(struct pthread));
5 return tp;
66}
77
88#define TLS_ABOVE_TP
99#define GAP_ABOVE_TP 0
10#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
1110
11#define TP_OFFSET 0x7000
1212#define DTP_OFFSET 0x8000
1313
1414// the kernel calls the ip "nip", it's the first saved value after the 32
1515// GPRs.
1616#define MC_PC gp_regs[32]
17
18#define CANARY canary_at_end
lib/libc/musl/arch/riscv64/bits/fcntl.h deleted-38
......@@ -1,38 +0,0 @@
1#define O_CREAT 0100
2#define O_EXCL 0200
3#define O_NOCTTY 0400
4#define O_TRUNC 01000
5#define O_APPEND 02000
6#define O_NONBLOCK 04000
7#define O_DSYNC 010000
8#define O_SYNC 04010000
9#define O_RSYNC 04010000
10#define O_DIRECTORY 0200000
11#define O_NOFOLLOW 0400000
12#define O_CLOEXEC 02000000
13
14#define O_ASYNC 020000
15#define O_DIRECT 040000
16#define O_LARGEFILE 0100000
17#define O_NOATIME 01000000
18#define O_PATH 010000000
19#define O_TMPFILE 020200000
20#define O_NDELAY O_NONBLOCK
21
22#define F_DUPFD 0
23#define F_GETFD 1
24#define F_SETFD 2
25#define F_GETFL 3
26#define F_SETFL 4
27#define F_GETLK 5
28#define F_SETLK 6
29#define F_SETLKW 7
30#define F_SETOWN 8
31#define F_GETOWN 9
32#define F_SETSIG 10
33#define F_GETSIG 11
34
35#define F_SETOWN_EX 15
36#define F_GETOWN_EX 16
37
38#define F_GETOWNER_UIDS 17
lib/libc/musl/arch/riscv64/bits/signal.h+2-2
......@@ -60,10 +60,10 @@ struct sigaltstack {
6060 size_t ss_size;
6161};
6262
63typedef struct ucontext_t
63typedef struct __ucontext
6464{
6565 unsigned long uc_flags;
66 struct ucontext_t *uc_link;
66 struct __ucontext *uc_link;
6767 stack_t uc_stack;
6868 sigset_t uc_sigmask;
6969 mcontext_t uc_mcontext;
lib/libc/musl/arch/riscv64/bits/syscall.h.in+4
......@@ -289,6 +289,10 @@
289289#define __NR_fspick 433
290290#define __NR_pidfd_open 434
291291#define __NR_clone3 435
292#define __NR_close_range 436
293#define __NR_openat2 437
294#define __NR_pidfd_getfd 438
295#define __NR_faccessat2 439
292296
293297#define __NR_sysriscv __NR_arch_specific_syscall
294298#define __NR_riscv_flush_icache (__NR_sysriscv + 15)
lib/libc/musl/arch/riscv64/pthread_arch.h+3-4
......@@ -1,13 +1,12 @@
1static inline struct pthread *__pthread_self()
1static inline uintptr_t __get_tp()
22{
3 char *tp;
3 uintptr_t tp;
44 __asm__ __volatile__("mv %0, tp" : "=r"(tp));
5 return (void *)(tp - sizeof(struct pthread));
5 return tp;
66}
77
88#define TLS_ABOVE_TP
99#define GAP_ABOVE_TP 0
10#define TP_ADJ(p) ((char *)p + sizeof(struct pthread))
1110
1211#define DTP_OFFSET 0x800
1312
lib/libc/musl/arch/s390x/bits/alltypes.h.in+4
......@@ -9,7 +9,11 @@
99TYPEDEF int wchar_t;
1010#endif
1111
12#if defined(__FLT_EVAL_METHOD__) && __FLT_EVAL_METHOD__ == 1
1213TYPEDEF double float_t;
14#else
15TYPEDEF float float_t;
16#endif
1317TYPEDEF double double_t;
1418
1519TYPEDEF struct { long long __ll; long double __ld; } max_align_t;
lib/libc/musl/arch/s390x/bits/float.h+5-1
......@@ -1,4 +1,8 @@
1#define FLT_EVAL_METHOD 1
1#ifdef __FLT_EVAL_METHOD__
2#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
3#else
4#define FLT_EVAL_METHOD 0
5#endif
26
37#define LDBL_TRUE_MIN 6.47517511943802511092443895822764655e-4966L
48#define LDBL_MIN 3.36210314311209350626267781732175260e-4932L
lib/libc/musl/arch/s390x/bits/syscall.h.in+4
......@@ -352,4 +352,8 @@
352352#define __NR_fspick 433
353353#define __NR_pidfd_open 434
354354#define __NR_clone3 435
355#define __NR_close_range 436
356#define __NR_openat2 437
357#define __NR_pidfd_getfd 438
358#define __NR_faccessat2 439
355359
lib/libc/musl/arch/s390x/pthread_arch.h+4-6
......@@ -1,14 +1,12 @@
1static inline struct pthread *__pthread_self()
1static inline uintptr_t __get_tp()
22{
3 struct pthread *self;
3 uintptr_t tp;
44 __asm__ (
55 "ear %0, %%a0\n"
66 "sllg %0, %0, 32\n"
77 "ear %0, %%a1\n"
8 : "=r"(self));
9 return self;
8 : "=r"(tp));
9 return tp;
1010}
1111
12#define TP_ADJ(p) (p)
13
1412#define MC_PC psw.addr
lib/libc/musl/arch/s390x/syscall_arch.h-2
......@@ -72,5 +72,3 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo
7272 register long r7 __asm__("r7") = f;
7373 __asm_syscall("+r"(r2), "r"(r1), "r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7));
7474}
75
76#define SYSCALL_USE_SOCKETCALL
lib/libc/musl/arch/x86_64/bits/fcntl.h deleted-40
......@@ -1,40 +0,0 @@
1#define O_CREAT 0100
2#define O_EXCL 0200
3#define O_NOCTTY 0400
4#define O_TRUNC 01000
5#define O_APPEND 02000
6#define O_NONBLOCK 04000
7#define O_DSYNC 010000
8#define O_SYNC 04010000
9#define O_RSYNC 04010000
10#define O_DIRECTORY 0200000
11#define O_NOFOLLOW 0400000
12#define O_CLOEXEC 02000000
13
14#define O_ASYNC 020000
15#define O_DIRECT 040000
16#define O_LARGEFILE 0
17#define O_NOATIME 01000000
18#define O_PATH 010000000
19#define O_TMPFILE 020200000
20#define O_NDELAY O_NONBLOCK
21
22#define F_DUPFD 0
23#define F_GETFD 1
24#define F_SETFD 2
25#define F_GETFL 3
26#define F_SETFL 4
27
28#define F_SETOWN 8
29#define F_GETOWN 9
30#define F_SETSIG 10
31#define F_GETSIG 11
32
33#define F_GETLK 5
34#define F_SETLK 6
35#define F_SETLKW 7
36
37#define F_SETOWN_EX 15
38#define F_GETOWN_EX 16
39
40#define F_GETOWNER_UIDS 17
lib/libc/musl/arch/x86_64/bits/syscall.h.in+4
......@@ -345,4 +345,8 @@
345345#define __NR_fspick 433
346346#define __NR_pidfd_open 434
347347#define __NR_clone3 435
348#define __NR_close_range 436
349#define __NR_openat2 437
350#define __NR_pidfd_getfd 438
351#define __NR_faccessat2 439
348352
lib/libc/musl/arch/x86_64/pthread_arch.h+4-6
......@@ -1,10 +1,8 @@
1static inline struct pthread *__pthread_self()
1static inline uintptr_t __get_tp()
22{
3 struct pthread *self;
4 __asm__ ("mov %%fs:0,%0" : "=r" (self) );
5 return self;
3 uintptr_t tp;
4 __asm__ ("mov %%fs:0,%0" : "=r" (tp) );
5 return tp;
66}
77
8#define TP_ADJ(p) (p)
9
108#define MC_PC gregs[REG_RIP]
lib/libc/musl/include/alltypes.h.in+2
......@@ -77,6 +77,8 @@ TYPEDEF struct __sigset_t { unsigned long __bits[128/sizeof(long)]; } sigset_t;
7777
7878STRUCT iovec { void *iov_base; size_t iov_len; };
7979
80STRUCT winsize { unsigned short ws_row, ws_col, ws_xpixel, ws_ypixel; };
81
8082TYPEDEF unsigned socklen_t;
8183TYPEDEF unsigned short sa_family_t;
8284
lib/libc/musl/include/elf.h+2
......@@ -603,6 +603,7 @@ typedef struct {
603603#define PT_GNU_EH_FRAME 0x6474e550
604604#define PT_GNU_STACK 0x6474e551
605605#define PT_GNU_RELRO 0x6474e552
606#define PT_GNU_PROPERTY 0x6474e553
606607#define PT_LOSUNW 0x6ffffffa
607608#define PT_SUNWBSS 0x6ffffffa
608609#define PT_SUNWSTACK 0x6ffffffb
......@@ -1085,6 +1086,7 @@ typedef struct {
10851086
10861087#define NT_GNU_BUILD_ID 3
10871088#define NT_GNU_GOLD_VERSION 4
1089#define NT_GNU_PROPERTY_TYPE_0 5
10881090
10891091
10901092
lib/libc/musl/include/netinet/if_ether.h+1
......@@ -59,6 +59,7 @@
5959#define ETH_P_PREAUTH 0x88C7
6060#define ETH_P_TIPC 0x88CA
6161#define ETH_P_LLDP 0x88CC
62#define ETH_P_MRP 0x88E3
6263#define ETH_P_MACSEC 0x88E5
6364#define ETH_P_8021AH 0x88E7
6465#define ETH_P_MVRP 0x88F5
lib/libc/musl/include/netinet/in.h+4-1
......@@ -101,8 +101,10 @@ uint16_t ntohs(uint16_t);
101101#define IPPROTO_MH 135
102102#define IPPROTO_UDPLITE 136
103103#define IPPROTO_MPLS 137
104#define IPPROTO_ETHERNET 143
104105#define IPPROTO_RAW 255
105#define IPPROTO_MAX 256
106#define IPPROTO_MPTCP 262
107#define IPPROTO_MAX 263
106108
107109#define IN6_IS_ADDR_UNSPECIFIED(a) \
108110 (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \
......@@ -200,6 +202,7 @@ uint16_t ntohs(uint16_t);
200202#define IP_CHECKSUM 23
201203#define IP_BIND_ADDRESS_NO_PORT 24
202204#define IP_RECVFRAGSIZE 25
205#define IP_RECVERR_RFC4884 26
203206#define IP_MULTICAST_IF 32
204207#define IP_MULTICAST_TTL 33
205208#define IP_MULTICAST_LOOP 34
lib/libc/musl/include/netinet/tcp.h+15-3
......@@ -78,6 +78,8 @@ enum {
7878 TCP_NLA_DSACK_DUPS,
7979 TCP_NLA_REORD_SEEN,
8080 TCP_NLA_SRTT,
81 TCP_NLA_TIMEOUT_REHASH,
82 TCP_NLA_BYTES_NOTSENT,
8183};
8284
8385#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
......@@ -181,6 +183,13 @@ struct tcphdr {
181183#define TCP_CA_Recovery 3
182184#define TCP_CA_Loss 4
183185
186enum tcp_fastopen_client_fail {
187 TFO_STATUS_UNSPEC,
188 TFO_COOKIE_UNAVAILABLE,
189 TFO_DATA_NOT_ACKED,
190 TFO_SYN_RETRANSMITTED,
191};
192
184193struct tcp_info {
185194 uint8_t tcpi_state;
186195 uint8_t tcpi_ca_state;
......@@ -189,7 +198,7 @@ struct tcp_info {
189198 uint8_t tcpi_backoff;
190199 uint8_t tcpi_options;
191200 uint8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
192 uint8_t tcpi_delivery_rate_app_limited : 1;
201 uint8_t tcpi_delivery_rate_app_limited : 1, tcpi_fastopen_client_fail : 2;
193202 uint32_t tcpi_rto;
194203 uint32_t tcpi_ato;
195204 uint32_t tcpi_snd_mss;
......@@ -240,14 +249,15 @@ struct tcp_info {
240249
241250#define TCP_MD5SIG_MAXKEYLEN 80
242251
243#define TCP_MD5SIG_FLAG_PREFIX 1
252#define TCP_MD5SIG_FLAG_PREFIX 0x1
253#define TCP_MD5SIG_FLAG_IFINDEX 0x2
244254
245255struct tcp_md5sig {
246256 struct sockaddr_storage tcpm_addr;
247257 uint8_t tcpm_flags;
248258 uint8_t tcpm_prefixlen;
249259 uint16_t tcpm_keylen;
250 uint32_t __tcpm_pad;
260 int tcpm_ifindex;
251261 uint8_t tcpm_key[TCP_MD5SIG_MAXKEYLEN];
252262};
253263
......@@ -275,6 +285,8 @@ struct tcp_zerocopy_receive {
275285 uint64_t address;
276286 uint32_t length;
277287 uint32_t recv_skip_hint;
288 uint32_t inq;
289 int32_t err;
278290};
279291
280292#endif
lib/libc/musl/include/netinet/udp.h+1
......@@ -35,6 +35,7 @@ struct udphdr {
3535#define UDP_ENCAP_GTP0 4
3636#define UDP_ENCAP_GTP1U 5
3737#define UDP_ENCAP_RXRPC 6
38#define TCP_ENCAP_ESPINTCP 7
3839
3940#define SOL_UDP 17
4041
lib/libc/musl/include/sched.h+1
......@@ -49,6 +49,7 @@ int sched_yield(void);
4949
5050#ifdef _GNU_SOURCE
5151#define CSIGNAL 0x000000ff
52#define CLONE_NEWTIME 0x00000080
5253#define CLONE_VM 0x00000100
5354#define CLONE_FS 0x00000200
5455#define CLONE_FILES 0x00000400
lib/libc/musl/include/signal.h+13-3
......@@ -180,14 +180,24 @@ struct sigevent {
180180 union sigval sigev_value;
181181 int sigev_signo;
182182 int sigev_notify;
183 void (*sigev_notify_function)(union sigval);
184 pthread_attr_t *sigev_notify_attributes;
185 char __pad[56-3*sizeof(long)];
183 union {
184 char __pad[64 - 2*sizeof(int) - sizeof(union sigval)];
185 pid_t sigev_notify_thread_id;
186 struct {
187 void (*sigev_notify_function)(union sigval);
188 pthread_attr_t *sigev_notify_attributes;
189 } __sev_thread;
190 } __sev_fields;
186191};
187192
193#define sigev_notify_thread_id __sev_fields.sigev_notify_thread_id
194#define sigev_notify_function __sev_fields.__sev_thread.sigev_notify_function
195#define sigev_notify_attributes __sev_fields.__sev_thread.sigev_notify_attributes
196
188197#define SIGEV_SIGNAL 0
189198#define SIGEV_NONE 1
190199#define SIGEV_THREAD 2
200#define SIGEV_THREAD_ID 4
191201
192202int __libc_current_sigrtmin(void);
193203int __libc_current_sigrtmax(void);
lib/libc/musl/include/stdlib.h+1
......@@ -145,6 +145,7 @@ int getloadavg(double *, int);
145145int clearenv(void);
146146#define WCOREDUMP(s) ((s) & 0x80)
147147#define WIFCONTINUED(s) ((s) == 0xffff)
148void *reallocarray (void *, size_t, size_t);
148149#endif
149150
150151#ifdef _GNU_SOURCE
lib/libc/musl/include/sys/fanotify.h+7-1
......@@ -55,8 +55,9 @@ struct fanotify_response {
5555#define FAN_OPEN_PERM 0x10000
5656#define FAN_ACCESS_PERM 0x20000
5757#define FAN_OPEN_EXEC_PERM 0x40000
58#define FAN_ONDIR 0x40000000
58#define FAN_DIR_MODIFY 0x00080000
5959#define FAN_EVENT_ON_CHILD 0x08000000
60#define FAN_ONDIR 0x40000000
6061#define FAN_CLOSE (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE)
6162#define FAN_MOVE (FAN_MOVED_FROM | FAN_MOVED_TO)
6263#define FAN_CLOEXEC 0x01
......@@ -70,6 +71,9 @@ struct fanotify_response {
7071#define FAN_ENABLE_AUDIT 0x40
7172#define FAN_REPORT_TID 0x100
7273#define FAN_REPORT_FID 0x200
74#define FAN_REPORT_DIR_FID 0x00000400
75#define FAN_REPORT_NAME 0x00000800
76#define FAN_REPORT_DFID_NAME (FAN_REPORT_DIR_FID | FAN_REPORT_NAME)
7377#define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK | FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE | FAN_UNLIMITED_MARKS)
7478#define FAN_MARK_ADD 0x01
7579#define FAN_MARK_REMOVE 0x02
......@@ -88,6 +92,8 @@ struct fanotify_response {
8892#define FAN_ALL_OUTGOING_EVENTS (FAN_ALL_EVENTS | FAN_ALL_PERM_EVENTS | FAN_Q_OVERFLOW)
8993#define FANOTIFY_METADATA_VERSION 3
9094#define FAN_EVENT_INFO_TYPE_FID 1
95#define FAN_EVENT_INFO_TYPE_DFID_NAME 2
96#define FAN_EVENT_INFO_TYPE_DFID 3
9197#define FAN_ALLOW 0x01
9298#define FAN_DENY 0x02
9399#define FAN_AUDIT 0x10
lib/libc/musl/include/sys/ioctl.h+2-7
......@@ -4,6 +4,8 @@
44extern "C" {
55#endif
66
7#define __NEED_struct_winsize
8
79#include <bits/alltypes.h>
810#include <bits/ioctl.h>
911
......@@ -47,13 +49,6 @@ extern "C" {
4749
4850#define TIOCSER_TEMT 1
4951
50struct winsize {
51 unsigned short ws_row;
52 unsigned short ws_col;
53 unsigned short ws_xpixel;
54 unsigned short ws_ypixel;
55};
56
5752#define SIOCADDRT 0x890B
5853#define SIOCDELRT 0x890C
5954#define SIOCRTMSG 0x890D
lib/libc/musl/include/sys/mman.h+1
......@@ -101,6 +101,7 @@ extern "C" {
101101#ifdef _GNU_SOURCE
102102#define MREMAP_MAYMOVE 1
103103#define MREMAP_FIXED 2
104#define MREMAP_DONTUNMAP 4
104105
105106#define MLOCK_ONFAULT 0x01
106107
lib/libc/musl/include/sys/personality.h+3
......@@ -5,7 +5,9 @@
55extern "C" {
66#endif
77
8#define UNAME26 0x0020000
89#define ADDR_NO_RANDOMIZE 0x0040000
10#define FDPIC_FUNCPTRS 0x0080000
911#define MMAP_PAGE_ZERO 0x0100000
1012#define ADDR_COMPAT_LAYOUT 0x0200000
1113#define READ_IMPLIES_EXEC 0x0400000
......@@ -17,6 +19,7 @@ extern "C" {
1719
1820#define PER_LINUX 0
1921#define PER_LINUX_32BIT ADDR_LIMIT_32BIT
22#define PER_LINUX_FDPIC FDPIC_FUNCPTRS
2023#define PER_SVR4 (1 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO)
2124#define PER_SVR3 (2 | STICKY_TIMEOUTS | SHORT_INODE)
2225#define PER_SCOSVR3 (3 | STICKY_TIMEOUTS | WHOLE_SECONDS | SHORT_INODE)
lib/libc/musl/include/sys/prctl.h+3
......@@ -158,6 +158,9 @@ struct prctl_mm_map {
158158#define PR_GET_TAGGED_ADDR_CTRL 56
159159#define PR_TAGGED_ADDR_ENABLE (1UL << 0)
160160
161#define PR_SET_IO_FLUSHER 57
162#define PR_GET_IO_FLUSHER 58
163
161164int prctl (int, ...);
162165
163166#ifdef __cplusplus
lib/libc/musl/include/sys/random.h+1
......@@ -10,6 +10,7 @@ extern "C" {
1010
1111#define GRND_NONBLOCK 0x0001
1212#define GRND_RANDOM 0x0002
13#define GRND_INSECURE 0x0004
1314
1415ssize_t getrandom(void *, size_t, unsigned);
1516
lib/libc/musl/include/termios.h+4
......@@ -8,6 +8,7 @@ extern "C" {
88#include <features.h>
99
1010#define __NEED_pid_t
11#define __NEED_struct_winsize
1112
1213#include <bits/alltypes.h>
1314
......@@ -27,6 +28,9 @@ int cfsetispeed (struct termios *, speed_t);
2728int tcgetattr (int, struct termios *);
2829int tcsetattr (int, int, const struct termios *);
2930
31int tcgetwinsize (int, struct winsize *);
32int tcsetwinsize (int, const struct winsize *);
33
3034int tcsendbreak (int, int);
3135int tcdrain (int);
3236int tcflush (int, int);
lib/libc/musl/include/unistd.h+2
......@@ -82,6 +82,7 @@ unsigned sleep(unsigned);
8282int pause(void);
8383
8484pid_t fork(void);
85pid_t _Fork(void);
8586int execve(const char *, char *const [], char *const []);
8687int execv(const char *, char *const []);
8788int execle(const char *, const char *, ...);
......@@ -190,6 +191,7 @@ int syncfs(int);
190191int euidaccess(const char *, int);
191192int eaccess(const char *, int);
192193ssize_t copy_file_range(int, off_t *, int, off_t *, size_t, unsigned);
194pid_t gettid(void);
193195#endif
194196
195197#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
lib/libc/musl/libc.s+16-1
......@@ -105,6 +105,9 @@ in6addr_loopback:
105105.globl _Exit
106106.type _Exit, %function;
107107_Exit:
108.globl _Fork
109.type _Fork, %function;
110_Fork:
108111.weak _IO_feof_unlocked
109112.type _IO_feof_unlocked, %function;
110113_IO_feof_unlocked:
......@@ -2116,6 +2119,9 @@ getsubopt:
21162119.globl gettext
21172120.type gettext, %function;
21182121gettext:
2122.globl gettid
2123.type gettid, %function;
2124gettid:
21192125.globl gettimeofday
21202126.type gettimeofday, %function;
21212127gettimeofday:
......@@ -2728,7 +2734,7 @@ lutimes:
27282734.weak madvise
27292735.type madvise, %function;
27302736madvise:
2731.globl malloc
2737.weak malloc
27322738.type malloc, %function;
27332739malloc:
27342740.globl malloc_usable_size
......@@ -3709,6 +3715,9 @@ readv:
37093715.globl realloc
37103716.type realloc, %function;
37113717realloc:
3718.globl reallocarray
3719.type reallocarray, %function;
3720reallocarray:
37123721.globl realpath
37133722.type realpath, %function;
37143723realpath:
......@@ -4543,6 +4552,9 @@ tcgetpgrp:
45434552.globl tcgetsid
45444553.type tcgetsid, %function;
45454554tcgetsid:
4555.globl tcgetwinsize
4556.type tcgetwinsize, %function;
4557tcgetwinsize:
45464558.globl tcsendbreak
45474559.type tcsendbreak, %function;
45484560tcsendbreak:
......@@ -4552,6 +4564,9 @@ tcsetattr:
45524564.globl tcsetpgrp
45534565.type tcsetpgrp, %function;
45544566tcsetpgrp:
4567.globl tcsetwinsize
4568.type tcsetwinsize, %function;
4569tcsetwinsize:
45554570.globl tdelete
45564571.type tdelete, %function;
45574572tdelete:
lib/libc/musl/src/aio/aio.c+28-10
......@@ -9,6 +9,12 @@
99#include "syscall.h"
1010#include "atomic.h"
1111#include "pthread_impl.h"
12#include "aio_impl.h"
13
14#define malloc __libc_malloc
15#define calloc __libc_calloc
16#define realloc __libc_realloc
17#define free __libc_free
1218
1319/* The following is a threads-based implementation of AIO with minimal
1420 * dependence on implementation details. Most synchronization is
......@@ -70,6 +76,10 @@ static struct aio_queue *****map;
7076static volatile int aio_fd_cnt;
7177volatile int __aio_fut;
7278
79static size_t io_thread_stack_size;
80
81#define MAX(a,b) ((a)>(b) ? (a) : (b))
82
7383static struct aio_queue *__aio_get_queue(int fd, int need)
7484{
7585 if (fd < 0) {
......@@ -84,6 +94,10 @@ static struct aio_queue *__aio_get_queue(int fd, int need)
8494 pthread_rwlock_unlock(&maplock);
8595 if (fcntl(fd, F_GETFD) < 0) return 0;
8696 pthread_rwlock_wrlock(&maplock);
97 if (!io_thread_stack_size) {
98 unsigned long val = __getauxval(AT_MINSIGSTKSZ);
99 io_thread_stack_size = MAX(MINSIGSTKSZ+2048, val+512);
100 }
87101 if (!map) map = calloc(sizeof *map, (-1U/2+1)>>24);
88102 if (!map) goto out;
89103 if (!map[a]) map[a] = calloc(sizeof **map, 256);
......@@ -259,15 +273,6 @@ static void *io_thread_func(void *ctx)
259273 return 0;
260274}
261275
262static size_t io_thread_stack_size = MINSIGSTKSZ+2048;
263static pthread_once_t init_stack_size_once;
264
265static void init_stack_size()
266{
267 unsigned long val = __getauxval(AT_MINSIGSTKSZ);
268 if (val > MINSIGSTKSZ) io_thread_stack_size = val + 512;
269}
270
271276static int submit(struct aiocb *cb, int op)
272277{
273278 int ret = 0;
......@@ -293,7 +298,6 @@ static int submit(struct aiocb *cb, int op)
293298 else
294299 pthread_attr_init(&a);
295300 } else {
296 pthread_once(&init_stack_size_once, init_stack_size);
297301 pthread_attr_init(&a);
298302 pthread_attr_setstacksize(&a, io_thread_stack_size);
299303 pthread_attr_setguardsize(&a, 0);
......@@ -392,6 +396,20 @@ int __aio_close(int fd)
392396 return fd;
393397}
394398
399void __aio_atfork(int who)
400{
401 if (who<0) {
402 pthread_rwlock_rdlock(&maplock);
403 return;
404 }
405 if (who>0 && map) for (int a=0; a<(-1U/2+1)>>24; a++)
406 if (map[a]) for (int b=0; b<256; b++)
407 if (map[a][b]) for (int c=0; c<256; c++)
408 if (map[a][b][c]) for (int d=0; d<256; d++)
409 map[a][b][c][d] = 0;
410 pthread_rwlock_unlock(&maplock);
411}
412
395413weak_alias(aio_cancel, aio_cancel64);
396414weak_alias(aio_error, aio_error64);
397415weak_alias(aio_fsync, aio_fsync64);
lib/libc/musl/src/aio/aio_suspend.c+1
......@@ -3,6 +3,7 @@
33#include <time.h>
44#include "atomic.h"
55#include "pthread_impl.h"
6#include "aio_impl.h"
67
78int aio_suspend(const struct aiocb *const cbs[], int cnt, const struct timespec *ts)
89{
lib/libc/musl/src/crypt/crypt_blowfish.c+23-15
......@@ -15,7 +15,7 @@
1515 * No copyright is claimed, and the software is hereby placed in the public
1616 * domain. In case this attempt to disclaim copyright and place the software
1717 * in the public domain is deemed null and void, then the software is
18 * Copyright (c) 1998-2012 Solar Designer and it is hereby released to the
18 * Copyright (c) 1998-2014 Solar Designer and it is hereby released to the
1919 * general public under the following terms:
2020 *
2121 * Redistribution and use in source and binary forms, with or without
......@@ -31,12 +31,12 @@
3131 * you place this code and any modifications you make under a license
3232 * of your choice.
3333 *
34 * This implementation is mostly compatible with OpenBSD's bcrypt.c (prefix
35 * "$2a$") by Niels Provos <provos at citi.umich.edu>, and uses some of his
36 * ideas. The password hashing algorithm was designed by David Mazieres
37 * <dm at lcs.mit.edu>. For more information on the level of compatibility,
38 * please refer to the comments in BF_set_key() below and to the included
39 * crypt(3) man page.
34 * This implementation is fully compatible with OpenBSD's bcrypt.c for prefix
35 * "$2b$", originally by Niels Provos <provos at citi.umich.edu>, and it uses
36 * some of his ideas. The password hashing algorithm was designed by David
37 * Mazieres <dm at lcs.mit.edu>. For information on the level of
38 * compatibility for bcrypt hash prefixes other than "$2b$", please refer to
39 * the comments in BF_set_key() below and to the included crypt(3) man page.
4040 *
4141 * There's a paper on the algorithm that explains its design decisions:
4242 *
......@@ -533,6 +533,7 @@ static void BF_set_key(const char *key, BF_key expanded, BF_key initial,
533533 * Valid combinations of settings are:
534534 *
535535 * Prefix "$2a$": bug = 0, safety = 0x10000
536 * Prefix "$2b$": bug = 0, safety = 0
536537 * Prefix "$2x$": bug = 1, safety = 0
537538 * Prefix "$2y$": bug = 0, safety = 0
538539 */
......@@ -596,12 +597,14 @@ static void BF_set_key(const char *key, BF_key expanded, BF_key initial,
596597 initial[0] ^= sign;
597598}
598599
600static const unsigned char flags_by_subtype[26] = {
601 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
602 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0
603};
604
599605static char *BF_crypt(const char *key, const char *setting,
600606 char *output, BF_word min)
601607{
602 static const unsigned char flags_by_subtype[26] =
603 {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0};
605608 struct {
606609 BF_ctx ctx;
607610 BF_key expanded_key;
......@@ -746,9 +749,11 @@ char *__crypt_blowfish(const char *key, const char *setting, char *output)
746749{
747750 const char *test_key = "8b \xd0\xc1\xd2\xcf\xcc\xd8";
748751 const char *test_setting = "$2a$00$abcdefghijklmnopqrstuu";
749 static const char test_hash[2][34] =
750 {"VUrPmXD6q/nVSSp7pNDhCR9071IfIRe\0\x55", /* $2x$ */
751 "i1D709vfamulimlGcq0qq3UvuUasvEa\0\x55"}; /* $2a$, $2y$ */
752 static const char test_hashes[2][34] = {
753 "i1D709vfamulimlGcq0qq3UvuUasvEa\0\x55", /* 'a', 'b', 'y' */
754 "VUrPmXD6q/nVSSp7pNDhCR9071IfIRe\0\x55", /* 'x' */
755 };
756 const char *test_hash = test_hashes[0];
752757 char *retval;
753758 const char *p;
754759 int ok;
......@@ -768,8 +773,11 @@ char *__crypt_blowfish(const char *key, const char *setting, char *output)
768773 * detected by the self-test.
769774 */
770775 memcpy(buf.s, test_setting, sizeof(buf.s));
771 if (retval)
776 if (retval) {
777 unsigned int flags = flags_by_subtype[setting[2] - 'a'];
778 test_hash = test_hashes[flags & 1];
772779 buf.s[2] = setting[2];
780 }
773781 memset(buf.o, 0x55, sizeof(buf.o));
774782 buf.o[sizeof(buf.o) - 1] = 0;
775783 p = BF_crypt(test_key, buf.s, buf.o, 1);
......@@ -777,7 +785,7 @@ char *__crypt_blowfish(const char *key, const char *setting, char *output)
777785 ok = (p == buf.o &&
778786 !memcmp(p, buf.s, 7 + 22) &&
779787 !memcmp(p + (7 + 22),
780 test_hash[buf.s[2] & 1],
788 test_hash,
781789 31 + 1 + 1 + 1));
782790
783791 {
lib/libc/musl/src/env/__init_tls.c+1-1
......@@ -67,7 +67,7 @@ void *__copy_tls(unsigned char *mem)
6767 }
6868#endif
6969 dtv[0] = libc.tls_cnt;
70 td->dtv = td->dtv_copy = dtv;
70 td->dtv = dtv;
7171 return td;
7272}
7373
lib/libc/musl/src/env/__stack_chk_fail.c+1-1
......@@ -9,7 +9,7 @@ void __init_ssp(void *entropy)
99 if (entropy) memcpy(&__stack_chk_guard, entropy, sizeof(uintptr_t));
1010 else __stack_chk_guard = (uintptr_t)&__stack_chk_guard * 1103515245;
1111
12 __pthread_self()->CANARY = __stack_chk_guard;
12 __pthread_self()->canary = __stack_chk_guard;
1313}
1414
1515void __stack_chk_fail(void)
lib/libc/musl/src/exit/abort.c-2
......@@ -6,8 +6,6 @@
66#include "lock.h"
77#include "ksigaction.h"
88
9hidden volatile int __abort_lock[1];
10
119_Noreturn void abort(void)
1210{
1311 raise(SIGABRT);
lib/libc/musl/src/exit/abort_lock.c created+3
......@@ -0,0 +1,3 @@
1#include "pthread_impl.h"
2
3volatile int __abort_lock[1];
lib/libc/musl/src/exit/assert.c-1
......@@ -4,6 +4,5 @@
44_Noreturn void __assert_fail(const char *expr, const char *file, int line, const char *func)
55{
66 fprintf(stderr, "Assertion failed: %s (%s: %s: %d)\n", expr, file, func, line);
7 fflush(NULL);
87 abort();
98}
lib/libc/musl/src/exit/at_quick_exit.c+2
......@@ -1,12 +1,14 @@
11#include <stdlib.h>
22#include "libc.h"
33#include "lock.h"
4#include "fork_impl.h"
45
56#define COUNT 32
67
78static void (*funcs[COUNT])(void);
89static int count;
910static volatile int lock[1];
11volatile int *const __at_quick_exit_lockptr = lock;
1012
1113void __funcs_on_quick_exit()
1214{
lib/libc/musl/src/exit/atexit.c+7
......@@ -2,6 +2,12 @@
22#include <stdint.h>
33#include "libc.h"
44#include "lock.h"
5#include "fork_impl.h"
6
7#define malloc __libc_malloc
8#define calloc __libc_calloc
9#define realloc undef
10#define free undef
511
612/* Ensure that at least 32 atexit handlers can be registered without malloc */
713#define COUNT 32
......@@ -15,6 +21,7 @@ static struct fl
1521
1622static int slot;
1723static volatile int lock[1];
24volatile int *const __atexit_lockptr = lock;
1825
1926void __funcs_on_exit()
2027{
lib/libc/musl/src/include/stdlib.h+6
......@@ -9,4 +9,10 @@ hidden int __mkostemps(char *, int, int);
99hidden int __ptsname_r(int, char *, size_t);
1010hidden char *__randname(char *);
1111
12hidden void *__libc_malloc(size_t);
13hidden void *__libc_malloc_impl(size_t);
14hidden void *__libc_calloc(size_t, size_t);
15hidden void *__libc_realloc(void *, size_t);
16hidden void __libc_free(void *);
17
1218#endif
lib/libc/musl/src/include/unistd.h-1
......@@ -8,7 +8,6 @@ extern char **__environ;
88hidden int __dup3(int, int, int);
99hidden int __mkostemps(char *, int, int);
1010hidden int __execvpe(const char *, char *const *, char *const *);
11hidden int __aio_close(int);
1211hidden off_t __lseek(int, off_t, int);
1312
1413#endif
lib/libc/musl/src/internal/aio_impl.h created+9
......@@ -0,0 +1,9 @@
1#ifndef AIO_IMPL_H
2#define AIO_IMPL_H
3
4extern hidden volatile int __aio_fut;
5
6extern hidden int __aio_close(int);
7extern hidden void __aio_atfork(int);
8
9#endif
lib/libc/musl/src/internal/fork_impl.h created+19
......@@ -0,0 +1,19 @@
1#include <features.h>
2
3extern hidden volatile int *const __at_quick_exit_lockptr;
4extern hidden volatile int *const __atexit_lockptr;
5extern hidden volatile int *const __dlerror_lockptr;
6extern hidden volatile int *const __gettext_lockptr;
7extern hidden volatile int *const __locale_lockptr;
8extern hidden volatile int *const __random_lockptr;
9extern hidden volatile int *const __sem_open_lockptr;
10extern hidden volatile int *const __stdio_ofl_lockptr;
11extern hidden volatile int *const __syslog_lockptr;
12extern hidden volatile int *const __timezone_lockptr;
13
14extern hidden volatile int *const __bump_lockptr;
15
16extern hidden volatile int *const __vmlock_lockptr;
17
18hidden void __malloc_atfork(int);
19hidden void __ldso_atfork(int);
lib/libc/musl/src/internal/libm.h+3
......@@ -267,5 +267,8 @@ hidden double __math_uflow(uint32_t);
267267hidden double __math_oflow(uint32_t);
268268hidden double __math_divzero(uint32_t);
269269hidden double __math_invalid(double);
270#if LDBL_MANT_DIG != DBL_MANT_DIG
271hidden long double __math_invalidl(long double);
272#endif
270273
271274#endif
lib/libc/musl/src/internal/locale_impl.h+2
......@@ -15,6 +15,8 @@ struct __locale_map {
1515 const struct __locale_map *next;
1616};
1717
18extern hidden volatile int __locale_lock[1];
19
1820extern hidden const struct __locale_map __c_dot_utf8;
1921extern hidden const struct __locale_struct __c_locale;
2022extern hidden const struct __locale_struct __c_dot_utf8_locale;
lib/libc/musl/src/internal/pthread_impl.h+29-14
......@@ -11,16 +11,25 @@
1111#include "atomic.h"
1212#include "futex.h"
1313
14#include "pthread_arch.h"
15
1416#define pthread __pthread
1517
1618struct pthread {
1719 /* Part 1 -- these fields may be external or
1820 * internal (accessed via asm) ABI. Do not change. */
1921 struct pthread *self;
22#ifndef TLS_ABOVE_TP
2023 uintptr_t *dtv;
24#endif
2125 struct pthread *prev, *next; /* non-ABI */
2226 uintptr_t sysinfo;
23 uintptr_t canary, canary2;
27#ifndef TLS_ABOVE_TP
28#ifdef CANARY_PAD
29 uintptr_t canary_pad;
30#endif
31 uintptr_t canary;
32#endif
2433
2534 /* Part 2 -- implementation details, non-ABI. */
2635 int tid;
......@@ -43,6 +52,7 @@ struct pthread {
4352 long off;
4453 volatile void *volatile pending;
4554 } robust_list;
55 int h_errno_val;
4656 volatile int timer_id;
4757 locale_t locale;
4858 volatile int killlock[1];
......@@ -51,21 +61,19 @@ struct pthread {
5161
5262 /* Part 3 -- the positions of these fields relative to
5363 * the end of the structure is external and internal ABI. */
54 uintptr_t canary_at_end;
55 uintptr_t *dtv_copy;
64#ifdef TLS_ABOVE_TP
65 uintptr_t canary;
66 uintptr_t *dtv;
67#endif
5668};
5769
5870enum {
59 DT_EXITING = 0,
71 DT_EXITED = 0,
72 DT_EXITING,
6073 DT_JOINABLE,
6174 DT_DETACHED,
6275};
6376
64struct __timer {
65 int timerid;
66 pthread_t thread;
67};
68
6977#define __SU (sizeof(size_t)/sizeof(int))
7078
7179#define _a_stacksize __u.__s[0]
......@@ -98,16 +106,22 @@ struct __timer {
98106#define _b_waiters2 __u.__vi[4]
99107#define _b_inst __u.__p[3]
100108
101#include "pthread_arch.h"
102
103#ifndef CANARY
104#define CANARY canary
109#ifndef TP_OFFSET
110#define TP_OFFSET 0
105111#endif
106112
107113#ifndef DTP_OFFSET
108114#define DTP_OFFSET 0
109115#endif
110116
117#ifdef TLS_ABOVE_TP
118#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + TP_OFFSET)
119#define __pthread_self() ((pthread_t)(__get_tp() - sizeof(struct __pthread) - TP_OFFSET))
120#else
121#define TP_ADJ(p) (p)
122#define __pthread_self() ((pthread_t)__get_tp())
123#endif
124
111125#ifndef tls_mod_off_t
112126#define tls_mod_off_t size_t
113127#endif
......@@ -141,7 +155,6 @@ hidden int __pthread_key_delete_impl(pthread_key_t);
141155
142156extern hidden volatile size_t __pthread_tsd_size;
143157extern hidden void *__pthread_tsd_main[];
144extern hidden volatile int __aio_fut;
145158extern hidden volatile int __eintr_valid_flag;
146159
147160hidden int __clone(int (*)(void *), void *, int, void *, ...);
......@@ -176,6 +189,8 @@ hidden void __tl_sync(pthread_t);
176189
177190extern hidden volatile int __thread_list_lock;
178191
192extern hidden volatile int __abort_lock[1];
193
179194extern hidden unsigned __default_stacksize;
180195extern hidden unsigned __default_guardsize;
181196
lib/libc/musl/src/internal/syscall.h+23-9
......@@ -2,6 +2,7 @@
22#define _INTERNAL_SYSCALL_H
33
44#include <features.h>
5#include <errno.h>
56#include <sys/syscall.h>
67#include "syscall_arch.h"
78
......@@ -57,15 +58,22 @@ hidden long __syscall_ret(unsigned long),
5758#define __syscall_cp(...) __SYSCALL_DISP(__syscall_cp,__VA_ARGS__)
5859#define syscall_cp(...) __syscall_ret(__syscall_cp(__VA_ARGS__))
5960
60#ifndef SYSCALL_USE_SOCKETCALL
61#define __socketcall(nm,a,b,c,d,e,f) __syscall(SYS_##nm, a, b, c, d, e, f)
62#define __socketcall_cp(nm,a,b,c,d,e,f) __syscall_cp(SYS_##nm, a, b, c, d, e, f)
63#else
64#define __socketcall(nm,a,b,c,d,e,f) __syscall(SYS_socketcall, __SC_##nm, \
65 ((long [6]){ (long)a, (long)b, (long)c, (long)d, (long)e, (long)f }))
66#define __socketcall_cp(nm,a,b,c,d,e,f) __syscall_cp(SYS_socketcall, __SC_##nm, \
67 ((long [6]){ (long)a, (long)b, (long)c, (long)d, (long)e, (long)f }))
68#endif
61static inline long __alt_socketcall(int sys, int sock, int cp, long a, long b, long c, long d, long e, long f)
62{
63 long r;
64 if (cp) r = __syscall_cp(sys, a, b, c, d, e, f);
65 else r = __syscall(sys, a, b, c, d, e, f);
66 if (r != -ENOSYS) return r;
67#ifdef SYS_socketcall
68 if (cp) r = __syscall_cp(SYS_socketcall, sock, ((long[6]){a, b, c, d, e, f}));
69 else r = __syscall(SYS_socketcall, sock, ((long[6]){a, b, c, d, e, f}));
70#endif
71 return r;
72}
73#define __socketcall(nm, a, b, c, d, e, f) __alt_socketcall(SYS_##nm, __SC_##nm, 0, \
74 (long)(a), (long)(b), (long)(c), (long)(d), (long)(e), (long)(f))
75#define __socketcall_cp(nm, a, b, c, d, e, f) __alt_socketcall(SYS_##nm, __SC_##nm, 1, \
76 (long)(a), (long)(b), (long)(c), (long)(d), (long)(e), (long)(f))
6977
7078/* fixup legacy 16-bit junk */
7179
......@@ -338,6 +346,12 @@ hidden long __syscall_ret(unsigned long),
338346#define __SC_recvmmsg 19
339347#define __SC_sendmmsg 20
340348
349/* This is valid only because all socket syscalls are made via
350 * socketcall, which always fills unused argument slots with zeros. */
351#ifndef SYS_accept
352#define SYS_accept SYS_accept4
353#endif
354
341355#ifndef SO_RCVTIMEO_OLD
342356#define SO_RCVTIMEO_OLD 20
343357#endif
lib/libc/musl/src/internal/version.h+1-1
......@@ -1 +1 @@
1#define VERSION "1.2.1"
1#define VERSION "1.2.2"
lib/libc/musl/src/ldso/dlerror.c+15-5
......@@ -4,6 +4,12 @@
44#include "pthread_impl.h"
55#include "dynlink.h"
66#include "lock.h"
7#include "fork_impl.h"
8
9#define malloc __libc_malloc
10#define calloc __libc_calloc
11#define realloc __libc_realloc
12#define free __libc_free
713
814char *dlerror()
915{
......@@ -19,6 +25,7 @@ char *dlerror()
1925
2026static volatile int freebuf_queue_lock[1];
2127static void **freebuf_queue;
28volatile int *const __dlerror_lockptr = freebuf_queue_lock;
2229
2330void __dl_thread_cleanup(void)
2431{
......@@ -35,13 +42,16 @@ void __dl_thread_cleanup(void)
3542hidden void __dl_vseterr(const char *fmt, va_list ap)
3643{
3744 LOCK(freebuf_queue_lock);
38 while (freebuf_queue) {
39 void **p = freebuf_queue;
40 freebuf_queue = *p;
41 free(p);
42 }
45 void **q = freebuf_queue;
46 freebuf_queue = 0;
4347 UNLOCK(freebuf_queue_lock);
4448
49 while (q) {
50 void **p = *q;
51 free(q);
52 q = p;
53 }
54
4555 va_list ap2;
4656 va_copy(ap2, ap);
4757 pthread_t self = __pthread_self();
lib/libc/musl/src/legacy/lutimes.c+7-5
......@@ -6,9 +6,11 @@
66int lutimes(const char *filename, const struct timeval tv[2])
77{
88 struct timespec times[2];
9 times[0].tv_sec = tv[0].tv_sec;
10 times[0].tv_nsec = tv[0].tv_usec * 1000;
11 times[1].tv_sec = tv[1].tv_sec;
12 times[1].tv_nsec = tv[1].tv_usec * 1000;
13 return utimensat(AT_FDCWD, filename, times, AT_SYMLINK_NOFOLLOW);
9 if (tv) {
10 times[0].tv_sec = tv[0].tv_sec;
11 times[0].tv_nsec = tv[0].tv_usec * 1000;
12 times[1].tv_sec = tv[1].tv_sec;
13 times[1].tv_nsec = tv[1].tv_usec * 1000;
14 }
15 return utimensat(AT_FDCWD, filename, tv ? times : 0, AT_SYMLINK_NOFOLLOW);
1416}
lib/libc/musl/src/linux/gettid.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include "pthread_impl.h"
4
5pid_t gettid(void)
6{
7 return __pthread_self()->tid;
8}
lib/libc/musl/src/linux/membarrier.c-5
......@@ -9,13 +9,8 @@ static void dummy_0(void)
99{
1010}
1111
12static void dummy_1(pthread_t t)
13{
14}
15
1612weak_alias(dummy_0, __tl_lock);
1713weak_alias(dummy_0, __tl_unlock);
18weak_alias(dummy_1, __tl_sync);
1914
2015static sem_t barrier_sem;
2116
lib/libc/musl/src/linux/setgroups.c+29-1
......@@ -1,8 +1,36 @@
11#define _GNU_SOURCE
22#include <unistd.h>
3#include <signal.h>
34#include "syscall.h"
5#include "libc.h"
6
7struct ctx {
8 size_t count;
9 const gid_t *list;
10 int ret;
11};
12
13static void do_setgroups(void *p)
14{
15 struct ctx *c = p;
16 if (c->ret<0) return;
17 int ret = __syscall(SYS_setgroups, c->count, c->list);
18 if (ret && !c->ret) {
19 /* If one thread fails to set groups after another has already
20 * succeeded, forcibly killing the process is the only safe
21 * thing to do. State is inconsistent and dangerous. Use
22 * SIGKILL because it is uncatchable. */
23 __block_all_sigs(0);
24 __syscall(SYS_kill, __syscall(SYS_getpid), SIGKILL);
25 }
26 c->ret = ret;
27}
428
529int setgroups(size_t count, const gid_t list[])
630{
7 return syscall(SYS_setgroups, count, list);
31 /* ret is initially nonzero so that failure of the first thread does not
32 * trigger the safety kill above. */
33 struct ctx c = { .count = count, .list = list, .ret = 1 };
34 __synccall(do_setgroups, &c);
35 return __syscall_ret(c.ret);
836}
lib/libc/musl/src/locale/dcngettext.c+9-1
......@@ -10,6 +10,12 @@
1010#include "atomic.h"
1111#include "pleval.h"
1212#include "lock.h"
13#include "fork_impl.h"
14
15#define malloc __libc_malloc
16#define calloc __libc_calloc
17#define realloc undef
18#define free undef
1319
1420struct binding {
1521 struct binding *next;
......@@ -34,9 +40,11 @@ static char *gettextdir(const char *domainname, size_t *dirlen)
3440 return 0;
3541}
3642
43static volatile int lock[1];
44volatile int *const __gettext_lockptr = lock;
45
3746char *bindtextdomain(const char *domainname, const char *dirname)
3847{
39 static volatile int lock[1];
4048 struct binding *p, *q;
4149
4250 if (!domainname) return 0;
lib/libc/musl/src/locale/freelocale.c+5
......@@ -1,6 +1,11 @@
11#include <stdlib.h>
22#include "locale_impl.h"
33
4#define malloc undef
5#define calloc undef
6#define realloc undef
7#define free __libc_free
8
49void freelocale(locale_t l)
510{
611 if (__loc_is_allocated(l)) free(l);
lib/libc/musl/src/locale/locale_map.c+11-11
......@@ -1,9 +1,16 @@
11#include <locale.h>
22#include <string.h>
33#include <sys/mman.h>
4#include <stdlib.h>
45#include "locale_impl.h"
56#include "libc.h"
67#include "lock.h"
8#include "fork_impl.h"
9
10#define malloc __libc_malloc
11#define calloc undef
12#define realloc undef
13#define free undef
714
815const char *__lctrans_impl(const char *msg, const struct __locale_map *lm)
916{
......@@ -21,9 +28,11 @@ static const char envvars[][12] = {
2128 "LC_MESSAGES",
2229};
2330
31volatile int __locale_lock[1];
32volatile int *const __locale_lockptr = __locale_lock;
33
2434const struct __locale_map *__get_locale(int cat, const char *val)
2535{
26 static volatile int lock[1];
2736 static void *volatile loc_head;
2837 const struct __locale_map *p;
2938 struct __locale_map *new = 0;
......@@ -54,20 +63,12 @@ const struct __locale_map *__get_locale(int cat, const char *val)
5463 for (p=loc_head; p; p=p->next)
5564 if (!strcmp(val, p->name)) return p;
5665
57 LOCK(lock);
58
59 for (p=loc_head; p; p=p->next)
60 if (!strcmp(val, p->name)) {
61 UNLOCK(lock);
62 return p;
63 }
64
6566 if (!libc.secure) path = getenv("MUSL_LOCPATH");
6667 /* FIXME: add a default path? */
6768
6869 if (path) for (; *path; path=z+!!*z) {
6970 z = __strchrnul(path, ':');
70 l = z - path - !!*z;
71 l = z - path;
7172 if (l >= sizeof buf - n - 2) continue;
7273 memcpy(buf, path, l);
7374 buf[l] = '/';
......@@ -108,6 +109,5 @@ const struct __locale_map *__get_locale(int cat, const char *val)
108109 * requested name was "C" or "POSIX". */
109110 if (!new && cat == LC_CTYPE) new = (void *)&__c_dot_utf8;
110111
111 UNLOCK(lock);
112112 return new;
113113}
lib/libc/musl/src/locale/newlocale.c+22-10
......@@ -2,16 +2,15 @@
22#include <string.h>
33#include <pthread.h>
44#include "locale_impl.h"
5#include "lock.h"
56
6static pthread_once_t default_locale_once;
7static struct __locale_struct default_locale, default_ctype_locale;
7#define malloc __libc_malloc
8#define calloc undef
9#define realloc undef
10#define free undef
811
9static void default_locale_init(void)
10{
11 for (int i=0; i<LC_ALL; i++)
12 default_locale.cat[i] = __get_locale(i, "");
13 default_ctype_locale.cat[LC_CTYPE] = default_locale.cat[LC_CTYPE];
14}
12static int default_locale_init_done;
13static struct __locale_struct default_locale, default_ctype_locale;
1514
1615int __loc_is_allocated(locale_t loc)
1716{
......@@ -19,7 +18,7 @@ int __loc_is_allocated(locale_t loc)
1918 && loc != &default_locale && loc != &default_ctype_locale;
2019}
2120
22locale_t __newlocale(int mask, const char *name, locale_t loc)
21static locale_t do_newlocale(int mask, const char *name, locale_t loc)
2322{
2423 struct __locale_struct tmp;
2524
......@@ -44,7 +43,12 @@ locale_t __newlocale(int mask, const char *name, locale_t loc)
4443
4544 /* And provide builtins for the initial default locale, and a
4645 * variant of the C locale honoring the default locale's encoding. */
47 pthread_once(&default_locale_once, default_locale_init);
46 if (!default_locale_init_done) {
47 for (int i=0; i<LC_ALL; i++)
48 default_locale.cat[i] = __get_locale(i, "");
49 default_ctype_locale.cat[LC_CTYPE] = default_locale.cat[LC_CTYPE];
50 default_locale_init_done = 1;
51 }
4852 if (!memcmp(&tmp, &default_locale, sizeof tmp)) return &default_locale;
4953 if (!memcmp(&tmp, &default_ctype_locale, sizeof tmp))
5054 return &default_ctype_locale;
......@@ -55,4 +59,12 @@ locale_t __newlocale(int mask, const char *name, locale_t loc)
5559 return loc;
5660}
5761
62locale_t __newlocale(int mask, const char *name, locale_t loc)
63{
64 LOCK(__locale_lock);
65 loc = do_newlocale(mask, name, loc);
66 UNLOCK(__locale_lock);
67 return loc;
68}
69
5870weak_alias(__newlocale, newlocale);
lib/libc/musl/src/locale/setlocale.c+5-6
......@@ -9,12 +9,11 @@ static char buf[LC_ALL*(LOCALE_NAME_MAX+1)];
99
1010char *setlocale(int cat, const char *name)
1111{
12 static volatile int lock[1];
1312 const struct __locale_map *lm;
1413
1514 if ((unsigned)cat > LC_ALL) return 0;
1615
17 LOCK(lock);
16 LOCK(__locale_lock);
1817
1918 /* For LC_ALL, setlocale is required to return a string which
2019 * encodes the current setting for all categories. The format of
......@@ -36,7 +35,7 @@ char *setlocale(int cat, const char *name)
3635 }
3736 lm = __get_locale(i, part);
3837 if (lm == LOC_MAP_FAILED) {
39 UNLOCK(lock);
38 UNLOCK(__locale_lock);
4039 return 0;
4140 }
4241 tmp_locale.cat[i] = lm;
......@@ -57,14 +56,14 @@ char *setlocale(int cat, const char *name)
5756 s += l+1;
5857 }
5958 *--s = 0;
60 UNLOCK(lock);
59 UNLOCK(__locale_lock);
6160 return same==LC_ALL ? (char *)part : buf;
6261 }
6362
6463 if (name) {
6564 lm = __get_locale(cat, name);
6665 if (lm == LOC_MAP_FAILED) {
67 UNLOCK(lock);
66 UNLOCK(__locale_lock);
6867 return 0;
6968 }
7069 libc.global_locale.cat[cat] = lm;
......@@ -73,7 +72,7 @@ char *setlocale(int cat, const char *name)
7372 }
7473 char *ret = lm ? (char *)lm->name : "C";
7574
76 UNLOCK(lock);
75 UNLOCK(__locale_lock);
7776
7877 return ret;
7978}
lib/libc/musl/src/malloc/free.c created+6
......@@ -0,0 +1,6 @@
1#include <stdlib.h>
2
3void free(void *p)
4{
5 return __libc_free(p);
6}
lib/libc/musl/src/malloc/libc_calloc.c created+4
......@@ -0,0 +1,4 @@
1#define calloc __libc_calloc
2#define malloc __libc_malloc
3
4#include "calloc.c"
lib/libc/musl/src/malloc/lite_malloc.c+17-2
......@@ -6,6 +6,7 @@
66#include "libc.h"
77#include "lock.h"
88#include "syscall.h"
9#include "fork_impl.h"
910
1011#define ALIGN 16
1112
......@@ -31,10 +32,12 @@ static int traverses_stack_p(uintptr_t old, uintptr_t new)
3132 return 0;
3233}
3334
35static volatile int lock[1];
36volatile int *const __bump_lockptr = lock;
37
3438static void *__simple_malloc(size_t n)
3539{
3640 static uintptr_t brk, cur, end;
37 static volatile int lock[1];
3841 static unsigned mmap_step;
3942 size_t align=1;
4043 void *p;
......@@ -100,4 +103,16 @@ static void *__simple_malloc(size_t n)
100103 return p;
101104}
102105
103weak_alias(__simple_malloc, malloc);
106weak_alias(__simple_malloc, __libc_malloc_impl);
107
108void *__libc_malloc(size_t n)
109{
110 return __libc_malloc_impl(n);
111}
112
113static void *default_malloc(size_t n)
114{
115 return __libc_malloc_impl(n);
116}
117
118weak_alias(default_malloc, malloc);
lib/libc/musl/src/malloc/mallocng/glue.h+17-1
......@@ -20,6 +20,10 @@
2020#define is_allzero __malloc_allzerop
2121#define dump_heap __dump_heap
2222
23#define malloc __libc_malloc_impl
24#define realloc __libc_realloc
25#define free __libc_free
26
2327#if USE_REAL_ASSERT
2428#include <assert.h>
2529#else
......@@ -56,7 +60,8 @@ __attribute__((__visibility__("hidden")))
5660extern int __malloc_lock[1];
5761
5862#define LOCK_OBJ_DEF \
59int __malloc_lock[1];
63int __malloc_lock[1]; \
64void __malloc_atfork(int who) { malloc_atfork(who); }
6065
6166static inline void rdlock()
6267{
......@@ -73,5 +78,16 @@ static inline void unlock()
7378static inline void upgradelock()
7479{
7580}
81static inline void resetlock()
82{
83 __malloc_lock[0] = 0;
84}
85
86static inline void malloc_atfork(int who)
87{
88 if (who<0) rdlock();
89 else if (who>0) resetlock();
90 else unlock();
91}
7692
7793#endif
lib/libc/musl/src/malloc/mallocng/malloc_usable_size.c+1
......@@ -3,6 +3,7 @@
33
44size_t malloc_usable_size(void *p)
55{
6 if (!p) return 0;
67 struct meta *g = get_meta(p);
78 int idx = get_slot_index(p);
89 size_t stride = get_stride(g);
lib/libc/musl/src/malloc/oldmalloc/aligned_alloc.c created+53
......@@ -0,0 +1,53 @@
1#include <stdlib.h>
2#include <stdint.h>
3#include <errno.h>
4#include "malloc_impl.h"
5
6void *aligned_alloc(size_t align, size_t len)
7{
8 unsigned char *mem, *new;
9
10 if ((align & -align) != align) {
11 errno = EINVAL;
12 return 0;
13 }
14
15 if (len > SIZE_MAX - align ||
16 (__malloc_replaced && !__aligned_alloc_replaced)) {
17 errno = ENOMEM;
18 return 0;
19 }
20
21 if (align <= SIZE_ALIGN)
22 return malloc(len);
23
24 if (!(mem = malloc(len + align-1)))
25 return 0;
26
27 new = (void *)((uintptr_t)mem + align-1 & -align);
28 if (new == mem) return mem;
29
30 struct chunk *c = MEM_TO_CHUNK(mem);
31 struct chunk *n = MEM_TO_CHUNK(new);
32
33 if (IS_MMAPPED(c)) {
34 /* Apply difference between aligned and original
35 * address to the "extra" field of mmapped chunk. */
36 n->psize = c->psize + (new-mem);
37 n->csize = c->csize - (new-mem);
38 return new;
39 }
40
41 struct chunk *t = NEXT_CHUNK(c);
42
43 /* Split the allocated chunk into two chunks. The aligned part
44 * that will be used has the size in its footer reduced by the
45 * difference between the aligned and original addresses, and
46 * the resulting size copied to its header. A new header and
47 * footer are written for the split-off part to be freed. */
48 n->psize = c->csize = C_INUSE | (new-mem);
49 n->csize = t->psize -= new-mem;
50
51 __bin_chunk(c);
52 return new;
53}
lib/libc/musl/src/malloc/oldmalloc/malloc.c created+552
......@@ -0,0 +1,552 @@
1#define _GNU_SOURCE
2#include <stdlib.h>
3#include <string.h>
4#include <limits.h>
5#include <stdint.h>
6#include <errno.h>
7#include <sys/mman.h>
8#include "libc.h"
9#include "atomic.h"
10#include "pthread_impl.h"
11#include "malloc_impl.h"
12#include "fork_impl.h"
13
14#define malloc __libc_malloc
15#define realloc __libc_realloc
16#define free __libc_free
17
18#if defined(__GNUC__) && defined(__PIC__)
19#define inline inline __attribute__((always_inline))
20#endif
21
22static struct {
23 volatile uint64_t binmap;
24 struct bin bins[64];
25 volatile int split_merge_lock[2];
26} mal;
27
28/* Synchronization tools */
29
30static inline void lock(volatile int *lk)
31{
32 int need_locks = libc.need_locks;
33 if (need_locks) {
34 while(a_swap(lk, 1)) __wait(lk, lk+1, 1, 1);
35 if (need_locks < 0) libc.need_locks = 0;
36 }
37}
38
39static inline void unlock(volatile int *lk)
40{
41 if (lk[0]) {
42 a_store(lk, 0);
43 if (lk[1]) __wake(lk, 1, 1);
44 }
45}
46
47static inline void lock_bin(int i)
48{
49 lock(mal.bins[i].lock);
50 if (!mal.bins[i].head)
51 mal.bins[i].head = mal.bins[i].tail = BIN_TO_CHUNK(i);
52}
53
54static inline void unlock_bin(int i)
55{
56 unlock(mal.bins[i].lock);
57}
58
59static int first_set(uint64_t x)
60{
61#if 1
62 return a_ctz_64(x);
63#else
64 static const char debruijn64[64] = {
65 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
66 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
67 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
68 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
69 };
70 static const char debruijn32[32] = {
71 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
72 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
73 };
74 if (sizeof(long) < 8) {
75 uint32_t y = x;
76 if (!y) {
77 y = x>>32;
78 return 32 + debruijn32[(y&-y)*0x076be629 >> 27];
79 }
80 return debruijn32[(y&-y)*0x076be629 >> 27];
81 }
82 return debruijn64[(x&-x)*0x022fdd63cc95386dull >> 58];
83#endif
84}
85
86static const unsigned char bin_tab[60] = {
87 32,33,34,35,36,36,37,37,38,38,39,39,
88 40,40,40,40,41,41,41,41,42,42,42,42,43,43,43,43,
89 44,44,44,44,44,44,44,44,45,45,45,45,45,45,45,45,
90 46,46,46,46,46,46,46,46,47,47,47,47,47,47,47,47,
91};
92
93static int bin_index(size_t x)
94{
95 x = x / SIZE_ALIGN - 1;
96 if (x <= 32) return x;
97 if (x < 512) return bin_tab[x/8-4];
98 if (x > 0x1c00) return 63;
99 return bin_tab[x/128-4] + 16;
100}
101
102static int bin_index_up(size_t x)
103{
104 x = x / SIZE_ALIGN - 1;
105 if (x <= 32) return x;
106 x--;
107 if (x < 512) return bin_tab[x/8-4] + 1;
108 return bin_tab[x/128-4] + 17;
109}
110
111#if 0
112void __dump_heap(int x)
113{
114 struct chunk *c;
115 int i;
116 for (c = (void *)mal.heap; CHUNK_SIZE(c); c = NEXT_CHUNK(c))
117 fprintf(stderr, "base %p size %zu (%d) flags %d/%d\n",
118 c, CHUNK_SIZE(c), bin_index(CHUNK_SIZE(c)),
119 c->csize & 15,
120 NEXT_CHUNK(c)->psize & 15);
121 for (i=0; i<64; i++) {
122 if (mal.bins[i].head != BIN_TO_CHUNK(i) && mal.bins[i].head) {
123 fprintf(stderr, "bin %d: %p\n", i, mal.bins[i].head);
124 if (!(mal.binmap & 1ULL<<i))
125 fprintf(stderr, "missing from binmap!\n");
126 } else if (mal.binmap & 1ULL<<i)
127 fprintf(stderr, "binmap wrongly contains %d!\n", i);
128 }
129}
130#endif
131
132/* This function returns true if the interval [old,new]
133 * intersects the 'len'-sized interval below &libc.auxv
134 * (interpreted as the main-thread stack) or below &b
135 * (the current stack). It is used to defend against
136 * buggy brk implementations that can cross the stack. */
137
138static int traverses_stack_p(uintptr_t old, uintptr_t new)
139{
140 const uintptr_t len = 8<<20;
141 uintptr_t a, b;
142
143 b = (uintptr_t)libc.auxv;
144 a = b > len ? b-len : 0;
145 if (new>a && old<b) return 1;
146
147 b = (uintptr_t)&b;
148 a = b > len ? b-len : 0;
149 if (new>a && old<b) return 1;
150
151 return 0;
152}
153
154/* Expand the heap in-place if brk can be used, or otherwise via mmap,
155 * using an exponential lower bound on growth by mmap to make
156 * fragmentation asymptotically irrelevant. The size argument is both
157 * an input and an output, since the caller needs to know the size
158 * allocated, which will be larger than requested due to page alignment
159 * and mmap minimum size rules. The caller is responsible for locking
160 * to prevent concurrent calls. */
161
162static void *__expand_heap(size_t *pn)
163{
164 static uintptr_t brk;
165 static unsigned mmap_step;
166 size_t n = *pn;
167
168 if (n > SIZE_MAX/2 - PAGE_SIZE) {
169 errno = ENOMEM;
170 return 0;
171 }
172 n += -n & PAGE_SIZE-1;
173
174 if (!brk) {
175 brk = __syscall(SYS_brk, 0);
176 brk += -brk & PAGE_SIZE-1;
177 }
178
179 if (n < SIZE_MAX-brk && !traverses_stack_p(brk, brk+n)
180 && __syscall(SYS_brk, brk+n)==brk+n) {
181 *pn = n;
182 brk += n;
183 return (void *)(brk-n);
184 }
185
186 size_t min = (size_t)PAGE_SIZE << mmap_step/2;
187 if (n < min) n = min;
188 void *area = __mmap(0, n, PROT_READ|PROT_WRITE,
189 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
190 if (area == MAP_FAILED) return 0;
191 *pn = n;
192 mmap_step++;
193 return area;
194}
195
196static struct chunk *expand_heap(size_t n)
197{
198 static void *end;
199 void *p;
200 struct chunk *w;
201
202 /* The argument n already accounts for the caller's chunk
203 * overhead needs, but if the heap can't be extended in-place,
204 * we need room for an extra zero-sized sentinel chunk. */
205 n += SIZE_ALIGN;
206
207 p = __expand_heap(&n);
208 if (!p) return 0;
209
210 /* If not just expanding existing space, we need to make a
211 * new sentinel chunk below the allocated space. */
212 if (p != end) {
213 /* Valid/safe because of the prologue increment. */
214 n -= SIZE_ALIGN;
215 p = (char *)p + SIZE_ALIGN;
216 w = MEM_TO_CHUNK(p);
217 w->psize = 0 | C_INUSE;
218 }
219
220 /* Record new heap end and fill in footer. */
221 end = (char *)p + n;
222 w = MEM_TO_CHUNK(end);
223 w->psize = n | C_INUSE;
224 w->csize = 0 | C_INUSE;
225
226 /* Fill in header, which may be new or may be replacing a
227 * zero-size sentinel header at the old end-of-heap. */
228 w = MEM_TO_CHUNK(p);
229 w->csize = n | C_INUSE;
230
231 return w;
232}
233
234static int adjust_size(size_t *n)
235{
236 /* Result of pointer difference must fit in ptrdiff_t. */
237 if (*n-1 > PTRDIFF_MAX - SIZE_ALIGN - PAGE_SIZE) {
238 if (*n) {
239 errno = ENOMEM;
240 return -1;
241 } else {
242 *n = SIZE_ALIGN;
243 return 0;
244 }
245 }
246 *n = (*n + OVERHEAD + SIZE_ALIGN - 1) & SIZE_MASK;
247 return 0;
248}
249
250static void unbin(struct chunk *c, int i)
251{
252 if (c->prev == c->next)
253 a_and_64(&mal.binmap, ~(1ULL<<i));
254 c->prev->next = c->next;
255 c->next->prev = c->prev;
256 c->csize |= C_INUSE;
257 NEXT_CHUNK(c)->psize |= C_INUSE;
258}
259
260static void bin_chunk(struct chunk *self, int i)
261{
262 self->next = BIN_TO_CHUNK(i);
263 self->prev = mal.bins[i].tail;
264 self->next->prev = self;
265 self->prev->next = self;
266 if (self->prev == BIN_TO_CHUNK(i))
267 a_or_64(&mal.binmap, 1ULL<<i);
268}
269
270static void trim(struct chunk *self, size_t n)
271{
272 size_t n1 = CHUNK_SIZE(self);
273 struct chunk *next, *split;
274
275 if (n >= n1 - DONTCARE) return;
276
277 next = NEXT_CHUNK(self);
278 split = (void *)((char *)self + n);
279
280 split->psize = n | C_INUSE;
281 split->csize = n1-n;
282 next->psize = n1-n;
283 self->csize = n | C_INUSE;
284
285 int i = bin_index(n1-n);
286 lock_bin(i);
287
288 bin_chunk(split, i);
289
290 unlock_bin(i);
291}
292
293void *malloc(size_t n)
294{
295 struct chunk *c;
296 int i, j;
297 uint64_t mask;
298
299 if (adjust_size(&n) < 0) return 0;
300
301 if (n > MMAP_THRESHOLD) {
302 size_t len = n + OVERHEAD + PAGE_SIZE - 1 & -PAGE_SIZE;
303 char *base = __mmap(0, len, PROT_READ|PROT_WRITE,
304 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
305 if (base == (void *)-1) return 0;
306 c = (void *)(base + SIZE_ALIGN - OVERHEAD);
307 c->csize = len - (SIZE_ALIGN - OVERHEAD);
308 c->psize = SIZE_ALIGN - OVERHEAD;
309 return CHUNK_TO_MEM(c);
310 }
311
312 i = bin_index_up(n);
313 if (i<63 && (mal.binmap & (1ULL<<i))) {
314 lock_bin(i);
315 c = mal.bins[i].head;
316 if (c != BIN_TO_CHUNK(i) && CHUNK_SIZE(c)-n <= DONTCARE) {
317 unbin(c, i);
318 unlock_bin(i);
319 return CHUNK_TO_MEM(c);
320 }
321 unlock_bin(i);
322 }
323 lock(mal.split_merge_lock);
324 for (mask = mal.binmap & -(1ULL<<i); mask; mask -= (mask&-mask)) {
325 j = first_set(mask);
326 lock_bin(j);
327 c = mal.bins[j].head;
328 if (c != BIN_TO_CHUNK(j)) {
329 unbin(c, j);
330 unlock_bin(j);
331 break;
332 }
333 unlock_bin(j);
334 }
335 if (!mask) {
336 c = expand_heap(n);
337 if (!c) {
338 unlock(mal.split_merge_lock);
339 return 0;
340 }
341 }
342 trim(c, n);
343 unlock(mal.split_merge_lock);
344 return CHUNK_TO_MEM(c);
345}
346
347int __malloc_allzerop(void *p)
348{
349 return IS_MMAPPED(MEM_TO_CHUNK(p));
350}
351
352void *realloc(void *p, size_t n)
353{
354 struct chunk *self, *next;
355 size_t n0, n1;
356 void *new;
357
358 if (!p) return malloc(n);
359
360 if (adjust_size(&n) < 0) return 0;
361
362 self = MEM_TO_CHUNK(p);
363 n1 = n0 = CHUNK_SIZE(self);
364
365 if (n<=n0 && n0-n<=DONTCARE) return p;
366
367 if (IS_MMAPPED(self)) {
368 size_t extra = self->psize;
369 char *base = (char *)self - extra;
370 size_t oldlen = n0 + extra;
371 size_t newlen = n + extra;
372 /* Crash on realloc of freed chunk */
373 if (extra & 1) a_crash();
374 if (newlen < PAGE_SIZE && (new = malloc(n-OVERHEAD))) {
375 n0 = n;
376 goto copy_free_ret;
377 }
378 newlen = (newlen + PAGE_SIZE-1) & -PAGE_SIZE;
379 if (oldlen == newlen) return p;
380 base = __mremap(base, oldlen, newlen, MREMAP_MAYMOVE);
381 if (base == (void *)-1)
382 goto copy_realloc;
383 self = (void *)(base + extra);
384 self->csize = newlen - extra;
385 return CHUNK_TO_MEM(self);
386 }
387
388 next = NEXT_CHUNK(self);
389
390 /* Crash on corrupted footer (likely from buffer overflow) */
391 if (next->psize != self->csize) a_crash();
392
393 if (n < n0) {
394 int i = bin_index_up(n);
395 int j = bin_index(n0);
396 if (i<j && (mal.binmap & (1ULL << i)))
397 goto copy_realloc;
398 struct chunk *split = (void *)((char *)self + n);
399 self->csize = split->psize = n | C_INUSE;
400 split->csize = next->psize = n0-n | C_INUSE;
401 __bin_chunk(split);
402 return CHUNK_TO_MEM(self);
403 }
404
405 lock(mal.split_merge_lock);
406
407 size_t nsize = next->csize & C_INUSE ? 0 : CHUNK_SIZE(next);
408 if (n0+nsize >= n) {
409 int i = bin_index(nsize);
410 lock_bin(i);
411 if (!(next->csize & C_INUSE)) {
412 unbin(next, i);
413 unlock_bin(i);
414 next = NEXT_CHUNK(next);
415 self->csize = next->psize = n0+nsize | C_INUSE;
416 trim(self, n);
417 unlock(mal.split_merge_lock);
418 return CHUNK_TO_MEM(self);
419 }
420 unlock_bin(i);
421 }
422 unlock(mal.split_merge_lock);
423
424copy_realloc:
425 /* As a last resort, allocate a new chunk and copy to it. */
426 new = malloc(n-OVERHEAD);
427 if (!new) return 0;
428copy_free_ret:
429 memcpy(new, p, (n<n0 ? n : n0) - OVERHEAD);
430 free(CHUNK_TO_MEM(self));
431 return new;
432}
433
434void __bin_chunk(struct chunk *self)
435{
436 struct chunk *next = NEXT_CHUNK(self);
437
438 /* Crash on corrupted footer (likely from buffer overflow) */
439 if (next->psize != self->csize) a_crash();
440
441 lock(mal.split_merge_lock);
442
443 size_t osize = CHUNK_SIZE(self), size = osize;
444
445 /* Since we hold split_merge_lock, only transition from free to
446 * in-use can race; in-use to free is impossible */
447 size_t psize = self->psize & C_INUSE ? 0 : CHUNK_PSIZE(self);
448 size_t nsize = next->csize & C_INUSE ? 0 : CHUNK_SIZE(next);
449
450 if (psize) {
451 int i = bin_index(psize);
452 lock_bin(i);
453 if (!(self->psize & C_INUSE)) {
454 struct chunk *prev = PREV_CHUNK(self);
455 unbin(prev, i);
456 self = prev;
457 size += psize;
458 }
459 unlock_bin(i);
460 }
461 if (nsize) {
462 int i = bin_index(nsize);
463 lock_bin(i);
464 if (!(next->csize & C_INUSE)) {
465 unbin(next, i);
466 next = NEXT_CHUNK(next);
467 size += nsize;
468 }
469 unlock_bin(i);
470 }
471
472 int i = bin_index(size);
473 lock_bin(i);
474
475 self->csize = size;
476 next->psize = size;
477 bin_chunk(self, i);
478 unlock(mal.split_merge_lock);
479
480 /* Replace middle of large chunks with fresh zero pages */
481 if (size > RECLAIM && (size^(size-osize)) > size-osize) {
482 uintptr_t a = (uintptr_t)self + SIZE_ALIGN+PAGE_SIZE-1 & -PAGE_SIZE;
483 uintptr_t b = (uintptr_t)next - SIZE_ALIGN & -PAGE_SIZE;
484#if 1
485 __madvise((void *)a, b-a, MADV_DONTNEED);
486#else
487 __mmap((void *)a, b-a, PROT_READ|PROT_WRITE,
488 MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);
489#endif
490 }
491
492 unlock_bin(i);
493}
494
495static void unmap_chunk(struct chunk *self)
496{
497 size_t extra = self->psize;
498 char *base = (char *)self - extra;
499 size_t len = CHUNK_SIZE(self) + extra;
500 /* Crash on double free */
501 if (extra & 1) a_crash();
502 __munmap(base, len);
503}
504
505void free(void *p)
506{
507 if (!p) return;
508
509 struct chunk *self = MEM_TO_CHUNK(p);
510
511 if (IS_MMAPPED(self))
512 unmap_chunk(self);
513 else
514 __bin_chunk(self);
515}
516
517void __malloc_donate(char *start, char *end)
518{
519 size_t align_start_up = (SIZE_ALIGN-1) & (-(uintptr_t)start - OVERHEAD);
520 size_t align_end_down = (SIZE_ALIGN-1) & (uintptr_t)end;
521
522 /* Getting past this condition ensures that the padding for alignment
523 * and header overhead will not overflow and will leave a nonzero
524 * multiple of SIZE_ALIGN bytes between start and end. */
525 if (end - start <= OVERHEAD + align_start_up + align_end_down)
526 return;
527 start += align_start_up + OVERHEAD;
528 end -= align_end_down;
529
530 struct chunk *c = MEM_TO_CHUNK(start), *n = MEM_TO_CHUNK(end);
531 c->psize = n->csize = C_INUSE;
532 c->csize = n->psize = C_INUSE | (end-start);
533 __bin_chunk(c);
534}
535
536void __malloc_atfork(int who)
537{
538 if (who<0) {
539 lock(mal.split_merge_lock);
540 for (int i=0; i<64; i++)
541 lock(mal.bins[i].lock);
542 } else if (!who) {
543 for (int i=0; i<64; i++)
544 unlock(mal.bins[i].lock);
545 unlock(mal.split_merge_lock);
546 } else {
547 for (int i=0; i<64; i++)
548 mal.bins[i].lock[0] = mal.bins[i].lock[1] = 0;
549 mal.split_merge_lock[1] = 0;
550 mal.split_merge_lock[0] = 0;
551 }
552}
lib/libc/musl/src/malloc/oldmalloc/malloc_impl.h created+39
......@@ -0,0 +1,39 @@
1#ifndef MALLOC_IMPL_H
2#define MALLOC_IMPL_H
3
4#include <sys/mman.h>
5#include "dynlink.h"
6
7struct chunk {
8 size_t psize, csize;
9 struct chunk *next, *prev;
10};
11
12struct bin {
13 volatile int lock[2];
14 struct chunk *head;
15 struct chunk *tail;
16};
17
18#define SIZE_ALIGN (4*sizeof(size_t))
19#define SIZE_MASK (-SIZE_ALIGN)
20#define OVERHEAD (2*sizeof(size_t))
21#define MMAP_THRESHOLD (0x1c00*SIZE_ALIGN)
22#define DONTCARE 16
23#define RECLAIM 163840
24
25#define CHUNK_SIZE(c) ((c)->csize & -2)
26#define CHUNK_PSIZE(c) ((c)->psize & -2)
27#define PREV_CHUNK(c) ((struct chunk *)((char *)(c) - CHUNK_PSIZE(c)))
28#define NEXT_CHUNK(c) ((struct chunk *)((char *)(c) + CHUNK_SIZE(c)))
29#define MEM_TO_CHUNK(p) (struct chunk *)((char *)(p) - OVERHEAD)
30#define CHUNK_TO_MEM(c) (void *)((char *)(c) + OVERHEAD)
31#define BIN_TO_CHUNK(i) (MEM_TO_CHUNK(&mal.bins[i].head))
32
33#define C_INUSE ((size_t)1)
34
35#define IS_MMAPPED(c) !((c)->csize & (C_INUSE))
36
37hidden void __bin_chunk(struct chunk *);
38
39#endif
lib/libc/musl/src/malloc/oldmalloc/malloc_usable_size.c created+9
......@@ -0,0 +1,9 @@
1#include <malloc.h>
2#include "malloc_impl.h"
3
4hidden void *(*const __realloc_dep)(void *, size_t) = realloc;
5
6size_t malloc_usable_size(void *p)
7{
8 return p ? CHUNK_SIZE(MEM_TO_CHUNK(p)) - OVERHEAD : 0;
9}
lib/libc/musl/src/malloc/realloc.c created+6
......@@ -0,0 +1,6 @@
1#include <stdlib.h>
2
3void *realloc(void *p, size_t n)
4{
5 return __libc_realloc(p, n);
6}
lib/libc/musl/src/malloc/reallocarray.c created+13
......@@ -0,0 +1,13 @@
1#define _BSD_SOURCE
2#include <errno.h>
3#include <stdlib.h>
4
5void *reallocarray(void *ptr, size_t m, size_t n)
6{
7 if (n && m > -1 / n) {
8 errno = ENOMEM;
9 return 0;
10 }
11
12 return realloc(ptr, m * n);
13}
lib/libc/musl/src/math/__math_invalidl.c created+9
......@@ -0,0 +1,9 @@
1#include <float.h>
2#include "libm.h"
3
4#if LDBL_MANT_DIG != DBL_MANT_DIG
5long double __math_invalidl(long double x)
6{
7 return (x - x) / (x - x);
8}
9#endif
lib/libc/musl/src/math/arm/fabs.c+1-1
......@@ -1,6 +1,6 @@
11#include <math.h>
22
3#if __ARM_PCS_VFP
3#if __ARM_PCS_VFP && __ARM_FP&8
44
55double fabs(double x)
66{
lib/libc/musl/src/math/arm/sqrt.c+1-1
......@@ -1,6 +1,6 @@
11#include <math.h>
22
3#if __ARM_PCS_VFP || (__VFP_FP__ && !__SOFTFP__)
3#if (__ARM_PCS_VFP || (__VFP_FP__ && !__SOFTFP__)) && (__ARM_FP&8)
44
55double sqrt(double x)
66{
lib/libc/musl/src/math/sqrt.c+147-173
......@@ -1,184 +1,158 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_sqrt.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunSoft, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/* sqrt(x)
13 * Return correctly rounded sqrt.
14 * ------------------------------------------
15 * | Use the hardware sqrt if you have one |
16 * ------------------------------------------
17 * Method:
18 * Bit by bit method using integer arithmetic. (Slow, but portable)
19 * 1. Normalization
20 * Scale x to y in [1,4) with even powers of 2:
21 * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
22 * sqrt(x) = 2^k * sqrt(y)
23 * 2. Bit by bit computation
24 * Let q = sqrt(y) truncated to i bit after binary point (q = 1),
25 * i 0
26 * i+1 2
27 * s = 2*q , and y = 2 * ( y - q ). (1)
28 * i i i i
29 *
30 * To compute q from q , one checks whether
31 * i+1 i
32 *
33 * -(i+1) 2
34 * (q + 2 ) <= y. (2)
35 * i
36 * -(i+1)
37 * If (2) is false, then q = q ; otherwise q = q + 2 .
38 * i+1 i i+1 i
39 *
40 * With some algebric manipulation, it is not difficult to see
41 * that (2) is equivalent to
42 * -(i+1)
43 * s + 2 <= y (3)
44 * i i
45 *
46 * The advantage of (3) is that s and y can be computed by
47 * i i
48 * the following recurrence formula:
49 * if (3) is false
50 *
51 * s = s , y = y ; (4)
52 * i+1 i i+1 i
53 *
54 * otherwise,
55 * -i -(i+1)
56 * s = s + 2 , y = y - s - 2 (5)
57 * i+1 i i+1 i i
58 *
59 * One may easily use induction to prove (4) and (5).
60 * Note. Since the left hand side of (3) contain only i+2 bits,
61 * it does not necessary to do a full (53-bit) comparison
62 * in (3).
63 * 3. Final rounding
64 * After generating the 53 bits result, we compute one more bit.
65 * Together with the remainder, we can decide whether the
66 * result is exact, bigger than 1/2ulp, or less than 1/2ulp
67 * (it will never equal to 1/2ulp).
68 * The rounding mode can be detected by checking whether
69 * huge + tiny is equal to huge, and whether huge - tiny is
70 * equal to huge for some floating point number "huge" and "tiny".
71 *
72 * Special cases:
73 * sqrt(+-0) = +-0 ... exact
74 * sqrt(inf) = inf
75 * sqrt(-ve) = NaN ... with invalid signal
76 * sqrt(NaN) = NaN ... with invalid signal for signaling NaN
77 */
78
1#include <stdint.h>
2#include <math.h>
793#include "libm.h"
4#include "sqrt_data.h"
805
81static const double tiny = 1.0e-300;
6#define FENV_SUPPORT 1
827
83double sqrt(double x)
8/* returns a*b*2^-32 - e, with error 0 <= e < 1. */
9static inline uint32_t mul32(uint32_t a, uint32_t b)
8410{
85 double z;
86 int32_t sign = (int)0x80000000;
87 int32_t ix0,s0,q,m,t,i;
88 uint32_t r,t1,s1,ix1,q1;
11 return (uint64_t)a*b >> 32;
12}
8913
90 EXTRACT_WORDS(ix0, ix1, x);
14/* returns a*b*2^-64 - e, with error 0 <= e < 3. */
15static inline uint64_t mul64(uint64_t a, uint64_t b)
16{
17 uint64_t ahi = a>>32;
18 uint64_t alo = a&0xffffffff;
19 uint64_t bhi = b>>32;
20 uint64_t blo = b&0xffffffff;
21 return ahi*bhi + (ahi*blo >> 32) + (alo*bhi >> 32);
22}
9123
92 /* take care of Inf and NaN */
93 if ((ix0&0x7ff00000) == 0x7ff00000) {
94 return x*x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */
95 }
96 /* take care of zero */
97 if (ix0 <= 0) {
98 if (((ix0&~sign)|ix1) == 0)
99 return x; /* sqrt(+-0) = +-0 */
100 if (ix0 < 0)
101 return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
102 }
103 /* normalize x */
104 m = ix0>>20;
105 if (m == 0) { /* subnormal x */
106 while (ix0 == 0) {
107 m -= 21;
108 ix0 |= (ix1>>11);
109 ix1 <<= 21;
110 }
111 for (i=0; (ix0&0x00100000) == 0; i++)
112 ix0<<=1;
113 m -= i - 1;
114 ix0 |= ix1>>(32-i);
115 ix1 <<= i;
116 }
117 m -= 1023; /* unbias exponent */
118 ix0 = (ix0&0x000fffff)|0x00100000;
119 if (m & 1) { /* odd m, double x to make it even */
120 ix0 += ix0 + ((ix1&sign)>>31);
121 ix1 += ix1;
122 }
123 m >>= 1; /* m = [m/2] */
124
125 /* generate sqrt(x) bit by bit */
126 ix0 += ix0 + ((ix1&sign)>>31);
127 ix1 += ix1;
128 q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */
129 r = 0x00200000; /* r = moving bit from right to left */
130
131 while (r != 0) {
132 t = s0 + r;
133 if (t <= ix0) {
134 s0 = t + r;
135 ix0 -= t;
136 q += r;
137 }
138 ix0 += ix0 + ((ix1&sign)>>31);
139 ix1 += ix1;
140 r >>= 1;
141 }
24double sqrt(double x)
25{
26 uint64_t ix, top, m;
14227
143 r = sign;
144 while (r != 0) {
145 t1 = s1 + r;
146 t = s0;
147 if (t < ix0 || (t == ix0 && t1 <= ix1)) {
148 s1 = t1 + r;
149 if ((t1&sign) == sign && (s1&sign) == 0)
150 s0++;
151 ix0 -= t;
152 if (ix1 < t1)
153 ix0--;
154 ix1 -= t1;
155 q1 += r;
156 }
157 ix0 += ix0 + ((ix1&sign)>>31);
158 ix1 += ix1;
159 r >>= 1;
28 /* special case handling. */
29 ix = asuint64(x);
30 top = ix >> 52;
31 if (predict_false(top - 0x001 >= 0x7ff - 0x001)) {
32 /* x < 0x1p-1022 or inf or nan. */
33 if (ix * 2 == 0)
34 return x;
35 if (ix == 0x7ff0000000000000)
36 return x;
37 if (ix > 0x7ff0000000000000)
38 return __math_invalid(x);
39 /* x is subnormal, normalize it. */
40 ix = asuint64(x * 0x1p52);
41 top = ix >> 52;
42 top -= 52;
16043 }
16144
162 /* use floating add to find out rounding direction */
163 if ((ix0|ix1) != 0) {
164 z = 1.0 - tiny; /* raise inexact flag */
165 if (z >= 1.0) {
166 z = 1.0 + tiny;
167 if (q1 == (uint32_t)0xffffffff) {
168 q1 = 0;
169 q++;
170 } else if (z > 1.0) {
171 if (q1 == (uint32_t)0xfffffffe)
172 q++;
173 q1 += 2;
174 } else
175 q1 += q1 & 1;
176 }
45 /* argument reduction:
46 x = 4^e m; with integer e, and m in [1, 4)
47 m: fixed point representation [2.62]
48 2^e is the exponent part of the result. */
49 int even = top & 1;
50 m = (ix << 11) | 0x8000000000000000;
51 if (even) m >>= 1;
52 top = (top + 0x3ff) >> 1;
53
54 /* approximate r ~ 1/sqrt(m) and s ~ sqrt(m) when m in [1,4)
55
56 initial estimate:
57 7bit table lookup (1bit exponent and 6bit significand).
58
59 iterative approximation:
60 using 2 goldschmidt iterations with 32bit int arithmetics
61 and a final iteration with 64bit int arithmetics.
62
63 details:
64
65 the relative error (e = r0 sqrt(m)-1) of a linear estimate
66 (r0 = a m + b) is |e| < 0.085955 ~ 0x1.6p-4 at best,
67 a table lookup is faster and needs one less iteration
68 6 bit lookup table (128b) gives |e| < 0x1.f9p-8
69 7 bit lookup table (256b) gives |e| < 0x1.fdp-9
70 for single and double prec 6bit is enough but for quad
71 prec 7bit is needed (or modified iterations). to avoid
72 one more iteration >=13bit table would be needed (16k).
73
74 a newton-raphson iteration for r is
75 w = r*r
76 u = 3 - m*w
77 r = r*u/2
78 can use a goldschmidt iteration for s at the end or
79 s = m*r
80
81 first goldschmidt iteration is
82 s = m*r
83 u = 3 - s*r
84 r = r*u/2
85 s = s*u/2
86 next goldschmidt iteration is
87 u = 3 - s*r
88 r = r*u/2
89 s = s*u/2
90 and at the end r is not computed only s.
91
92 they use the same amount of operations and converge at the
93 same quadratic rate, i.e. if
94 r1 sqrt(m) - 1 = e, then
95 r2 sqrt(m) - 1 = -3/2 e^2 - 1/2 e^3
96 the advantage of goldschmidt is that the mul for s and r
97 are independent (computed in parallel), however it is not
98 "self synchronizing": it only uses the input m in the
99 first iteration so rounding errors accumulate. at the end
100 or when switching to larger precision arithmetics rounding
101 errors dominate so the first iteration should be used.
102
103 the fixed point representations are
104 m: 2.30 r: 0.32, s: 2.30, d: 2.30, u: 2.30, three: 2.30
105 and after switching to 64 bit
106 m: 2.62 r: 0.64, s: 2.62, d: 2.62, u: 2.62, three: 2.62 */
107
108 static const uint64_t three = 0xc0000000;
109 uint64_t r, s, d, u, i;
110
111 i = (ix >> 46) % 128;
112 r = (uint32_t)__rsqrt_tab[i] << 16;
113 /* |r sqrt(m) - 1| < 0x1.fdp-9 */
114 s = mul32(m>>32, r);
115 /* |s/sqrt(m) - 1| < 0x1.fdp-9 */
116 d = mul32(s, r);
117 u = three - d;
118 r = mul32(r, u) << 1;
119 /* |r sqrt(m) - 1| < 0x1.7bp-16 */
120 s = mul32(s, u) << 1;
121 /* |s/sqrt(m) - 1| < 0x1.7bp-16 */
122 d = mul32(s, r);
123 u = three - d;
124 r = mul32(r, u) << 1;
125 /* |r sqrt(m) - 1| < 0x1.3704p-29 (measured worst-case) */
126 r = r << 32;
127 s = mul64(m, r);
128 d = mul64(s, r);
129 u = (three<<32) - d;
130 s = mul64(s, u); /* repr: 3.61 */
131 /* -0x1p-57 < s - sqrt(m) < 0x1.8001p-61 */
132 s = (s - 2) >> 9; /* repr: 12.52 */
133 /* -0x1.09p-52 < s - sqrt(m) < -0x1.fffcp-63 */
134
135 /* s < sqrt(m) < s + 0x1.09p-52,
136 compute nearest rounded result:
137 the nearest result to 52 bits is either s or s+0x1p-52,
138 we can decide by comparing (2^52 s + 0.5)^2 to 2^104 m. */
139 uint64_t d0, d1, d2;
140 double y, t;
141 d0 = (m << 42) - s*s;
142 d1 = s - d0;
143 d2 = d1 + s + 1;
144 s += d1 >> 63;
145 s &= 0x000fffffffffffff;
146 s |= top << 52;
147 y = asdouble(s);
148 if (FENV_SUPPORT) {
149 /* handle rounding modes and inexact exception:
150 only (s+1)^2 == 2^42 m case is exact otherwise
151 add a tiny value to cause the fenv effects. */
152 uint64_t tiny = predict_false(d2==0) ? 0 : 0x0010000000000000;
153 tiny |= (d1^d2) & 0x8000000000000000;
154 t = asdouble(tiny);
155 y = eval_as_double(y + t);
177156 }
178 ix0 = (q>>1) + 0x3fe00000;
179 ix1 = q1>>1;
180 if (q&1)
181 ix1 |= sign;
182 INSERT_WORDS(z, ix0 + ((uint32_t)m << 20), ix1);
183 return z;
157 return y;
184158}
lib/libc/musl/src/math/sqrt_data.c created+19
......@@ -0,0 +1,19 @@
1#include "sqrt_data.h"
2const uint16_t __rsqrt_tab[128] = {
30xb451,0xb2f0,0xb196,0xb044,0xaef9,0xadb6,0xac79,0xab43,
40xaa14,0xa8eb,0xa7c8,0xa6aa,0xa592,0xa480,0xa373,0xa26b,
50xa168,0xa06a,0x9f70,0x9e7b,0x9d8a,0x9c9d,0x9bb5,0x9ad1,
60x99f0,0x9913,0x983a,0x9765,0x9693,0x95c4,0x94f8,0x9430,
70x936b,0x92a9,0x91ea,0x912e,0x9075,0x8fbe,0x8f0a,0x8e59,
80x8daa,0x8cfe,0x8c54,0x8bac,0x8b07,0x8a64,0x89c4,0x8925,
90x8889,0x87ee,0x8756,0x86c0,0x862b,0x8599,0x8508,0x8479,
100x83ec,0x8361,0x82d8,0x8250,0x81c9,0x8145,0x80c2,0x8040,
110xff02,0xfd0e,0xfb25,0xf947,0xf773,0xf5aa,0xf3ea,0xf234,
120xf087,0xeee3,0xed47,0xebb3,0xea27,0xe8a3,0xe727,0xe5b2,
130xe443,0xe2dc,0xe17a,0xe020,0xdecb,0xdd7d,0xdc34,0xdaf1,
140xd9b3,0xd87b,0xd748,0xd61a,0xd4f1,0xd3cd,0xd2ad,0xd192,
150xd07b,0xcf69,0xce5b,0xcd51,0xcc4a,0xcb48,0xca4a,0xc94f,
160xc858,0xc764,0xc674,0xc587,0xc49d,0xc3b7,0xc2d4,0xc1f4,
170xc116,0xc03c,0xbf65,0xbe90,0xbdbe,0xbcef,0xbc23,0xbb59,
180xba91,0xb9cc,0xb90a,0xb84a,0xb78c,0xb6d0,0xb617,0xb560,
19};
lib/libc/musl/src/math/sqrt_data.h created+13
......@@ -0,0 +1,13 @@
1#ifndef _SQRT_DATA_H
2#define _SQRT_DATA_H
3
4#include <features.h>
5#include <stdint.h>
6
7/* if x in [1,2): i = (int)(64*x);
8 if x in [2,4): i = (int)(32*x-64);
9 __rsqrt_tab[i]*2^-16 is estimating 1/sqrt(x) with small relative error:
10 |__rsqrt_tab[i]*0x1p-16*sqrt(x) - 1| < -0x1.fdp-9 < 2^-8 */
11extern hidden const uint16_t __rsqrt_tab[128];
12
13#endif
lib/libc/musl/src/math/sqrtf.c+70-70
......@@ -1,83 +1,83 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_sqrtf.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 */
5/*
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 *
9 * Developed at SunPro, a Sun Microsystems, Inc. business.
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
12 * is preserved.
13 * ====================================================
14 */
15
1#include <stdint.h>
2#include <math.h>
163#include "libm.h"
4#include "sqrt_data.h"
175
18static const float tiny = 1.0e-30;
6#define FENV_SUPPORT 1
197
20float sqrtf(float x)
8static inline uint32_t mul32(uint32_t a, uint32_t b)
219{
22 float z;
23 int32_t sign = (int)0x80000000;
24 int32_t ix,s,q,m,t,i;
25 uint32_t r;
10 return (uint64_t)a*b >> 32;
11}
2612
27 GET_FLOAT_WORD(ix, x);
13/* see sqrt.c for more detailed comments. */
2814
29 /* take care of Inf and NaN */
30 if ((ix&0x7f800000) == 0x7f800000)
31 return x*x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */
15float sqrtf(float x)
16{
17 uint32_t ix, m, m1, m0, even, ey;
3218
33 /* take care of zero */
34 if (ix <= 0) {
35 if ((ix&~sign) == 0)
36 return x; /* sqrt(+-0) = +-0 */
37 if (ix < 0)
38 return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
39 }
40 /* normalize x */
41 m = ix>>23;
42 if (m == 0) { /* subnormal x */
43 for (i = 0; (ix&0x00800000) == 0; i++)
44 ix<<=1;
45 m -= i - 1;
19 ix = asuint(x);
20 if (predict_false(ix - 0x00800000 >= 0x7f800000 - 0x00800000)) {
21 /* x < 0x1p-126 or inf or nan. */
22 if (ix * 2 == 0)
23 return x;
24 if (ix == 0x7f800000)
25 return x;
26 if (ix > 0x7f800000)
27 return __math_invalidf(x);
28 /* x is subnormal, normalize it. */
29 ix = asuint(x * 0x1p23f);
30 ix -= 23 << 23;
4631 }
47 m -= 127; /* unbias exponent */
48 ix = (ix&0x007fffff)|0x00800000;
49 if (m&1) /* odd m, double x to make it even */
50 ix += ix;
51 m >>= 1; /* m = [m/2] */
5232
53 /* generate sqrt(x) bit by bit */
54 ix += ix;
55 q = s = 0; /* q = sqrt(x) */
56 r = 0x01000000; /* r = moving bit from right to left */
33 /* x = 4^e m; with int e and m in [1, 4). */
34 even = ix & 0x00800000;
35 m1 = (ix << 8) | 0x80000000;
36 m0 = (ix << 7) & 0x7fffffff;
37 m = even ? m0 : m1;
5738
58 while (r != 0) {
59 t = s + r;
60 if (t <= ix) {
61 s = t+r;
62 ix -= t;
63 q += r;
64 }
65 ix += ix;
66 r >>= 1;
67 }
39 /* 2^e is the exponent part of the return value. */
40 ey = ix >> 1;
41 ey += 0x3f800000 >> 1;
42 ey &= 0x7f800000;
43
44 /* compute r ~ 1/sqrt(m), s ~ sqrt(m) with 2 goldschmidt iterations. */
45 static const uint32_t three = 0xc0000000;
46 uint32_t r, s, d, u, i;
47 i = (ix >> 17) % 128;
48 r = (uint32_t)__rsqrt_tab[i] << 16;
49 /* |r*sqrt(m) - 1| < 0x1p-8 */
50 s = mul32(m, r);
51 /* |s/sqrt(m) - 1| < 0x1p-8 */
52 d = mul32(s, r);
53 u = three - d;
54 r = mul32(r, u) << 1;
55 /* |r*sqrt(m) - 1| < 0x1.7bp-16 */
56 s = mul32(s, u) << 1;
57 /* |s/sqrt(m) - 1| < 0x1.7bp-16 */
58 d = mul32(s, r);
59 u = three - d;
60 s = mul32(s, u);
61 /* -0x1.03p-28 < s/sqrt(m) - 1 < 0x1.fp-31 */
62 s = (s - 1)>>6;
63 /* s < sqrt(m) < s + 0x1.08p-23 */
6864
69 /* use floating add to find out rounding direction */
70 if (ix != 0) {
71 z = 1.0f - tiny; /* raise inexact flag */
72 if (z >= 1.0f) {
73 z = 1.0f + tiny;
74 if (z > 1.0f)
75 q += 2;
76 else
77 q += q & 1;
78 }
65 /* compute nearest rounded result. */
66 uint32_t d0, d1, d2;
67 float y, t;
68 d0 = (m << 16) - s*s;
69 d1 = s - d0;
70 d2 = d1 + s + 1;
71 s += d1 >> 31;
72 s &= 0x007fffff;
73 s |= ey;
74 y = asfloat(s);
75 if (FENV_SUPPORT) {
76 /* handle rounding and inexact exception. */
77 uint32_t tiny = predict_false(d2==0) ? 0 : 0x01000000;
78 tiny |= (d1^d2) & 0x80000000;
79 t = asfloat(tiny);
80 y = eval_as_float(y + t);
7981 }
80 ix = (q>>1) + 0x3f000000;
81 SET_FLOAT_WORD(z, ix + ((uint32_t)m << 23));
82 return z;
82 return y;
8383}
lib/libc/musl/src/math/sqrtl.c+253-1
......@@ -1,7 +1,259 @@
1#include <stdint.h>
12#include <math.h>
3#include <float.h>
4#include "libm.h"
25
6#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
37long double sqrtl(long double x)
48{
5 /* FIXME: implement in C, this is for LDBL_MANT_DIG == 64 only */
69 return sqrt(x);
710}
11#elif (LDBL_MANT_DIG == 113 || LDBL_MANT_DIG == 64) && LDBL_MAX_EXP == 16384
12#include "sqrt_data.h"
13
14#define FENV_SUPPORT 1
15
16typedef struct {
17 uint64_t hi;
18 uint64_t lo;
19} u128;
20
21/* top: 16 bit sign+exponent, x: significand. */
22static inline long double mkldbl(uint64_t top, u128 x)
23{
24 union ldshape u;
25#if LDBL_MANT_DIG == 113
26 u.i2.hi = x.hi;
27 u.i2.lo = x.lo;
28 u.i2.hi &= 0x0000ffffffffffff;
29 u.i2.hi |= top << 48;
30#elif LDBL_MANT_DIG == 64
31 u.i.se = top;
32 u.i.m = x.lo;
33 /* force the top bit on non-zero (and non-subnormal) results. */
34 if (top & 0x7fff)
35 u.i.m |= 0x8000000000000000;
36#endif
37 return u.f;
38}
39
40/* return: top 16 bit is sign+exp and following bits are the significand. */
41static inline u128 asu128(long double x)
42{
43 union ldshape u = {.f=x};
44 u128 r;
45#if LDBL_MANT_DIG == 113
46 r.hi = u.i2.hi;
47 r.lo = u.i2.lo;
48#elif LDBL_MANT_DIG == 64
49 r.lo = u.i.m<<49;
50 /* ignore the top bit: pseudo numbers are not handled. */
51 r.hi = u.i.m>>15;
52 r.hi &= 0x0000ffffffffffff;
53 r.hi |= (uint64_t)u.i.se << 48;
54#endif
55 return r;
56}
57
58/* returns a*b*2^-32 - e, with error 0 <= e < 1. */
59static inline uint32_t mul32(uint32_t a, uint32_t b)
60{
61 return (uint64_t)a*b >> 32;
62}
63
64/* returns a*b*2^-64 - e, with error 0 <= e < 3. */
65static inline uint64_t mul64(uint64_t a, uint64_t b)
66{
67 uint64_t ahi = a>>32;
68 uint64_t alo = a&0xffffffff;
69 uint64_t bhi = b>>32;
70 uint64_t blo = b&0xffffffff;
71 return ahi*bhi + (ahi*blo >> 32) + (alo*bhi >> 32);
72}
73
74static inline u128 add64(u128 a, uint64_t b)
75{
76 u128 r;
77 r.lo = a.lo + b;
78 r.hi = a.hi;
79 if (r.lo < a.lo)
80 r.hi++;
81 return r;
82}
83
84static inline u128 add128(u128 a, u128 b)
85{
86 u128 r;
87 r.lo = a.lo + b.lo;
88 r.hi = a.hi + b.hi;
89 if (r.lo < a.lo)
90 r.hi++;
91 return r;
92}
93
94static inline u128 sub64(u128 a, uint64_t b)
95{
96 u128 r;
97 r.lo = a.lo - b;
98 r.hi = a.hi;
99 if (a.lo < b)
100 r.hi--;
101 return r;
102}
103
104static inline u128 sub128(u128 a, u128 b)
105{
106 u128 r;
107 r.lo = a.lo - b.lo;
108 r.hi = a.hi - b.hi;
109 if (a.lo < b.lo)
110 r.hi--;
111 return r;
112}
113
114/* a<<n, 0 <= n <= 127 */
115static inline u128 lsh(u128 a, int n)
116{
117 if (n == 0)
118 return a;
119 if (n >= 64) {
120 a.hi = a.lo<<(n-64);
121 a.lo = 0;
122 } else {
123 a.hi = (a.hi<<n) | (a.lo>>(64-n));
124 a.lo = a.lo<<n;
125 }
126 return a;
127}
128
129/* a>>n, 0 <= n <= 127 */
130static inline u128 rsh(u128 a, int n)
131{
132 if (n == 0)
133 return a;
134 if (n >= 64) {
135 a.lo = a.hi>>(n-64);
136 a.hi = 0;
137 } else {
138 a.lo = (a.lo>>n) | (a.hi<<(64-n));
139 a.hi = a.hi>>n;
140 }
141 return a;
142}
143
144/* returns a*b exactly. */
145static inline u128 mul64_128(uint64_t a, uint64_t b)
146{
147 u128 r;
148 uint64_t ahi = a>>32;
149 uint64_t alo = a&0xffffffff;
150 uint64_t bhi = b>>32;
151 uint64_t blo = b&0xffffffff;
152 uint64_t lo1 = ((ahi*blo)&0xffffffff) + ((alo*bhi)&0xffffffff) + (alo*blo>>32);
153 uint64_t lo2 = (alo*blo)&0xffffffff;
154 r.hi = ahi*bhi + (ahi*blo>>32) + (alo*bhi>>32) + (lo1>>32);
155 r.lo = (lo1<<32) + lo2;
156 return r;
157}
158
159/* returns a*b*2^-128 - e, with error 0 <= e < 7. */
160static inline u128 mul128(u128 a, u128 b)
161{
162 u128 hi = mul64_128(a.hi, b.hi);
163 uint64_t m1 = mul64(a.hi, b.lo);
164 uint64_t m2 = mul64(a.lo, b.hi);
165 return add64(add64(hi, m1), m2);
166}
167
168/* returns a*b % 2^128. */
169static inline u128 mul128_tail(u128 a, u128 b)
170{
171 u128 lo = mul64_128(a.lo, b.lo);
172 lo.hi += a.hi*b.lo + a.lo*b.hi;
173 return lo;
174}
175
176
177/* see sqrt.c for detailed comments. */
178
179long double sqrtl(long double x)
180{
181 u128 ix, ml;
182 uint64_t top;
183
184 ix = asu128(x);
185 top = ix.hi >> 48;
186 if (predict_false(top - 0x0001 >= 0x7fff - 0x0001)) {
187 /* x < 0x1p-16382 or inf or nan. */
188 if (2*ix.hi == 0 && ix.lo == 0)
189 return x;
190 if (ix.hi == 0x7fff000000000000 && ix.lo == 0)
191 return x;
192 if (top >= 0x7fff)
193 return __math_invalidl(x);
194 /* x is subnormal, normalize it. */
195 ix = asu128(x * 0x1p112);
196 top = ix.hi >> 48;
197 top -= 112;
198 }
199
200 /* x = 4^e m; with int e and m in [1, 4) */
201 int even = top & 1;
202 ml = lsh(ix, 15);
203 ml.hi |= 0x8000000000000000;
204 if (even) ml = rsh(ml, 1);
205 top = (top + 0x3fff) >> 1;
206
207 /* r ~ 1/sqrt(m) */
208 static const uint64_t three = 0xc0000000;
209 uint64_t r, s, d, u, i;
210 i = (ix.hi >> 42) % 128;
211 r = (uint32_t)__rsqrt_tab[i] << 16;
212 /* |r sqrt(m) - 1| < 0x1p-8 */
213 s = mul32(ml.hi>>32, r);
214 d = mul32(s, r);
215 u = three - d;
216 r = mul32(u, r) << 1;
217 /* |r sqrt(m) - 1| < 0x1.7bp-16, switch to 64bit */
218 r = r<<32;
219 s = mul64(ml.hi, r);
220 d = mul64(s, r);
221 u = (three<<32) - d;
222 r = mul64(u, r) << 1;
223 /* |r sqrt(m) - 1| < 0x1.a5p-31 */
224 s = mul64(u, s) << 1;
225 d = mul64(s, r);
226 u = (three<<32) - d;
227 r = mul64(u, r) << 1;
228 /* |r sqrt(m) - 1| < 0x1.c001p-59, switch to 128bit */
229
230 static const u128 threel = {.hi=three<<32, .lo=0};
231 u128 rl, sl, dl, ul;
232 rl.hi = r;
233 rl.lo = 0;
234 sl = mul128(ml, rl);
235 dl = mul128(sl, rl);
236 ul = sub128(threel, dl);
237 sl = mul128(ul, sl); /* repr: 3.125 */
238 /* -0x1p-116 < s - sqrt(m) < 0x3.8001p-125 */
239 sl = rsh(sub64(sl, 4), 125-(LDBL_MANT_DIG-1));
240 /* s < sqrt(m) < s + 1 ULP + tiny */
241
242 long double y;
243 u128 d2, d1, d0;
244 d0 = sub128(lsh(ml, 2*(LDBL_MANT_DIG-1)-126), mul128_tail(sl,sl));
245 d1 = sub128(sl, d0);
246 d2 = add128(add64(sl, 1), d1);
247 sl = add64(sl, d1.hi >> 63);
248 y = mkldbl(top, sl);
249 if (FENV_SUPPORT) {
250 /* handle rounding modes and inexact exception. */
251 top = predict_false((d2.hi|d2.lo)==0) ? 0 : 1;
252 top |= ((d1.hi^d2.hi)&0x8000000000000000) >> 48;
253 y += mkldbl(top, (u128){0});
254 }
255 return y;
256}
257#else
258#error unsupported long double format
259#endif
lib/libc/musl/src/misc/ioctl.c+13-5
......@@ -4,6 +4,7 @@
44#include <time.h>
55#include <sys/time.h>
66#include <stddef.h>
7#include <stdint.h>
78#include <string.h>
89#include "syscall.h"
910
......@@ -28,6 +29,12 @@ struct ioctl_compat_map {
2829 * number producing macros; only size of result is meaningful. */
2930#define new_misaligned(n) struct { int i; time_t t; char c[(n)-4]; }
3031
32struct v4l2_event {
33 uint32_t a;
34 uint64_t b[8];
35 uint32_t c[2], ts[2], d[9];
36};
37
3138static const struct ioctl_compat_map compat_map[] = {
3239 { SIOCGSTAMP, SIOCGSTAMP_OLD, 8, R, 0, OFFS(0, 4) },
3340 { SIOCGSTAMPNS, SIOCGSTAMPNS_OLD, 8, R, 0, OFFS(0, 4) },
......@@ -49,13 +56,14 @@ static const struct ioctl_compat_map compat_map[] = {
4956 { 0, 0, 8, WR, 1, OFFS(0,4) }, /* snd_pcm_mmap_control */
5057
5158 /* VIDIOC_QUERYBUF, VIDIOC_QBUF, VIDIOC_DQBUF, VIDIOC_PREPARE_BUF */
52 { _IOWR('V', 9, new_misaligned(72)), _IOWR('V', 9, char[72]), 72, WR, 0, OFFS(20) },
53 { _IOWR('V', 15, new_misaligned(72)), _IOWR('V', 15, char[72]), 72, WR, 0, OFFS(20) },
54 { _IOWR('V', 17, new_misaligned(72)), _IOWR('V', 17, char[72]), 72, WR, 0, OFFS(20) },
55 { _IOWR('V', 93, new_misaligned(72)), _IOWR('V', 93, char[72]), 72, WR, 0, OFFS(20) },
59 { _IOWR('V', 9, new_misaligned(68)), _IOWR('V', 9, char[68]), 68, WR, 1, OFFS(20, 24) },
60 { _IOWR('V', 15, new_misaligned(68)), _IOWR('V', 15, char[68]), 68, WR, 1, OFFS(20, 24) },
61 { _IOWR('V', 17, new_misaligned(68)), _IOWR('V', 17, char[68]), 68, WR, 1, OFFS(20, 24) },
62 { _IOWR('V', 93, new_misaligned(68)), _IOWR('V', 93, char[68]), 68, WR, 1, OFFS(20, 24) },
5663
5764 /* VIDIOC_DQEVENT */
58 { _IOR('V', 89, new_misaligned(96)), _IOR('V', 89, char[96]), 96, R, 0, OFFS(76,80) },
65 { _IOR('V', 89, new_misaligned(120)), _IOR('V', 89, struct v4l2_event), sizeof(struct v4l2_event),
66 R, 0, OFFS(offsetof(struct v4l2_event, ts[0]), offsetof(struct v4l2_event, ts[1])) },
5967
6068 /* VIDIOC_OMAP3ISP_STAT_REQ */
6169 { _IOWR('V', 192+6, char[32]), _IOWR('V', 192+6, char[24]), 22, WR, 0, OFFS(0,4) },
lib/libc/musl/src/misc/realpath.c+136-23
......@@ -1,43 +1,156 @@
11#include <stdlib.h>
22#include <limits.h>
3#include <sys/stat.h>
4#include <fcntl.h>
53#include <errno.h>
64#include <unistd.h>
75#include <string.h>
8#include "syscall.h"
6
7static size_t slash_len(const char *s)
8{
9 const char *s0 = s;
10 while (*s == '/') s++;
11 return s-s0;
12}
913
1014char *realpath(const char *restrict filename, char *restrict resolved)
1115{
12 int fd;
13 ssize_t r;
14 struct stat st1, st2;
15 char buf[15+3*sizeof(int)];
16 char tmp[PATH_MAX];
16 char stack[PATH_MAX+1];
17 char output[PATH_MAX];
18 size_t p, q, l, l0, cnt=0, nup=0;
19 int check_dir=0;
1720
1821 if (!filename) {
1922 errno = EINVAL;
2023 return 0;
2124 }
25 l = strnlen(filename, sizeof stack);
26 if (!l) {
27 errno = ENOENT;
28 return 0;
29 }
30 if (l >= PATH_MAX) goto toolong;
31 p = sizeof stack - l - 1;
32 q = 0;
33 memcpy(stack+p, filename, l+1);
34
35 /* Main loop. Each iteration pops the next part from stack of
36 * remaining path components and consumes any slashes that follow.
37 * If not a link, it's moved to output; if a link, contents are
38 * pushed to the stack. */
39restart:
40 for (; ; p+=slash_len(stack+p)) {
41 /* If stack starts with /, the whole component is / or //
42 * and the output state must be reset. */
43 if (stack[p] == '/') {
44 check_dir=0;
45 nup=0;
46 q=0;
47 output[q++] = '/';
48 p++;
49 /* Initial // is special. */
50 if (stack[p] == '/' && stack[p+1] != '/')
51 output[q++] = '/';
52 continue;
53 }
54
55 char *z = __strchrnul(stack+p, '/');
56 l0 = l = z-(stack+p);
2257
23 fd = sys_open(filename, O_PATH|O_NONBLOCK|O_CLOEXEC);
24 if (fd < 0) return 0;
25 __procfdname(buf, fd);
58 if (!l && !check_dir) break;
2659
27 r = readlink(buf, tmp, sizeof tmp - 1);
28 if (r < 0) goto err;
29 tmp[r] = 0;
60 /* Skip any . component but preserve check_dir status. */
61 if (l==1 && stack[p]=='.') {
62 p += l;
63 continue;
64 }
3065
31 fstat(fd, &st1);
32 r = stat(tmp, &st2);
33 if (r<0 || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) {
34 if (!r) errno = ELOOP;
35 goto err;
66 /* Copy next component onto output at least temporarily, to
67 * call readlink, but wait to advance output position until
68 * determining it's not a link. */
69 if (q && output[q-1] != '/') {
70 if (!p) goto toolong;
71 stack[--p] = '/';
72 l++;
73 }
74 if (q+l >= PATH_MAX) goto toolong;
75 memcpy(output+q, stack+p, l);
76 output[q+l] = 0;
77 p += l;
78
79 int up = 0;
80 if (l0==2 && stack[p-2]=='.' && stack[p-1]=='.') {
81 up = 1;
82 /* Any non-.. path components we could cancel start
83 * after nup repetitions of the 3-byte string "../";
84 * if there are none, accumulate .. components to
85 * later apply to cwd, if needed. */
86 if (q <= 3*nup) {
87 nup++;
88 q += l;
89 continue;
90 }
91 /* When previous components are already known to be
92 * directories, processing .. can skip readlink. */
93 if (!check_dir) goto skip_readlink;
94 }
95 ssize_t k = readlink(output, stack, p);
96 if (k==p) goto toolong;
97 if (!k) {
98 errno = ENOENT;
99 return 0;
100 }
101 if (k<0) {
102 if (errno != EINVAL) return 0;
103skip_readlink:
104 check_dir = 0;
105 if (up) {
106 while(q && output[q-1]!='/') q--;
107 if (q>1 && (q>2 || output[0]!='/')) q--;
108 continue;
109 }
110 if (l0) q += l;
111 check_dir = stack[p];
112 continue;
113 }
114 if (++cnt == SYMLOOP_MAX) {
115 errno = ELOOP;
116 return 0;
117 }
118
119 /* If link contents end in /, strip any slashes already on
120 * stack to avoid /->// or //->/// or spurious toolong. */
121 if (stack[k-1]=='/') while (stack[p]=='/') p++;
122 p -= k;
123 memmove(stack+p, stack, k);
124
125 /* Skip the stack advancement in case we have a new
126 * absolute base path. */
127 goto restart;
36128 }
37129
38 __syscall(SYS_close, fd);
39 return resolved ? strcpy(resolved, tmp) : strdup(tmp);
40err:
41 __syscall(SYS_close, fd);
130 output[q] = 0;
131
132 if (output[0] != '/') {
133 if (!getcwd(stack, sizeof stack)) return 0;
134 l = strlen(stack);
135 /* Cancel any initial .. components. */
136 p = 0;
137 while (nup--) {
138 while(l>1 && stack[l-1]!='/') l--;
139 if (l>1) l--;
140 p += 2;
141 if (p<q) p++;
142 }
143 if (q-p && stack[l-1]!='/') stack[l++] = '/';
144 if (l + (q-p) + 1 >= PATH_MAX) goto toolong;
145 memmove(output + l, output + p, q - p + 1);
146 memcpy(output, stack, l);
147 q = l + q-p;
148 }
149
150 if (resolved) return memcpy(resolved, output, q+1);
151 else return strdup(output);
152
153toolong:
154 errno = ENAMETOOLONG;
42155 return 0;
43156}
lib/libc/musl/src/misc/setrlimit.c+17-20
......@@ -6,25 +6,8 @@
66#define MIN(a, b) ((a)<(b) ? (a) : (b))
77#define FIX(x) do{ if ((x)>=SYSCALL_RLIM_INFINITY) (x)=RLIM_INFINITY; }while(0)
88
9static int __setrlimit(int resource, const struct rlimit *rlim)
10{
11 unsigned long k_rlim[2];
12 struct rlimit tmp;
13 if (SYSCALL_RLIM_INFINITY != RLIM_INFINITY) {
14 tmp = *rlim;
15 FIX(tmp.rlim_cur);
16 FIX(tmp.rlim_max);
17 rlim = &tmp;
18 }
19 int ret = __syscall(SYS_prlimit64, 0, resource, rlim, 0);
20 if (ret != -ENOSYS) return ret;
21 k_rlim[0] = MIN(rlim->rlim_cur, MIN(-1UL, SYSCALL_RLIM_INFINITY));
22 k_rlim[1] = MIN(rlim->rlim_max, MIN(-1UL, SYSCALL_RLIM_INFINITY));
23 return __syscall(SYS_setrlimit, resource, k_rlim);
24}
25
269struct ctx {
27 const struct rlimit *rlim;
10 unsigned long lim[2];
2811 int res;
2912 int err;
3013};
......@@ -33,12 +16,26 @@ static void do_setrlimit(void *p)
3316{
3417 struct ctx *c = p;
3518 if (c->err>0) return;
36 c->err = -__setrlimit(c->res, c->rlim);
19 c->err = -__syscall(SYS_setrlimit, c->res, c->lim);
3720}
3821
3922int setrlimit(int resource, const struct rlimit *rlim)
4023{
41 struct ctx c = { .res = resource, .rlim = rlim, .err = -1 };
24 struct rlimit tmp;
25 if (SYSCALL_RLIM_INFINITY != RLIM_INFINITY) {
26 tmp = *rlim;
27 FIX(tmp.rlim_cur);
28 FIX(tmp.rlim_max);
29 rlim = &tmp;
30 }
31 int ret = __syscall(SYS_prlimit64, 0, resource, rlim, 0);
32 if (ret != -ENOSYS) return __syscall_ret(ret);
33
34 struct ctx c = {
35 .lim[0] = MIN(rlim->rlim_cur, MIN(-1UL, SYSCALL_RLIM_INFINITY)),
36 .lim[1] = MIN(rlim->rlim_max, MIN(-1UL, SYSCALL_RLIM_INFINITY)),
37 .res = resource, .err = -1
38 };
4239 __synccall(do_setrlimit, &c);
4340 if (c.err) {
4441 if (c.err>0) errno = c.err;
lib/libc/musl/src/misc/syslog.c+2
......@@ -10,6 +10,7 @@
1010#include <errno.h>
1111#include <fcntl.h>
1212#include "lock.h"
13#include "fork_impl.h"
1314
1415static volatile int lock[1];
1516static char log_ident[32];
......@@ -17,6 +18,7 @@ static int log_opt;
1718static int log_facility = LOG_USER;
1819static int log_mask = 0xff;
1920static int log_fd = -1;
21volatile int *const __syslog_lockptr = lock;
2022
2123int setlogmask(int maskpri)
2224{
lib/libc/musl/src/multibyte/wcsnrtombs.c+19-27
......@@ -1,41 +1,33 @@
11#include <wchar.h>
2#include <limits.h>
3#include <string.h>
24
35size_t wcsnrtombs(char *restrict dst, const wchar_t **restrict wcs, size_t wn, size_t n, mbstate_t *restrict st)
46{
5 size_t l, cnt=0, n2;
6 char *s, buf[256];
77 const wchar_t *ws = *wcs;
8 const wchar_t *tmp_ws;
9
10 if (!dst) s = buf, n = sizeof buf;
11 else s = dst;
12
13 while ( ws && n && ( (n2=wn)>=n || n2>32 ) ) {
14 if (n2>=n) n2=n;
15 tmp_ws = ws;
16 l = wcsrtombs(s, &ws, n2, 0);
17 if (!(l+1)) {
18 cnt = l;
19 n = 0;
8 size_t cnt = 0;
9 if (!dst) n=0;
10 while (ws && wn) {
11 char tmp[MB_LEN_MAX];
12 size_t l = wcrtomb(n<MB_LEN_MAX ? tmp : dst, *ws, 0);
13 if (l==-1) {
14 cnt = -1;
2015 break;
2116 }
22 if (s != buf) {
23 s += l;
17 if (dst) {
18 if (n<MB_LEN_MAX) {
19 if (l>n) break;
20 memcpy(dst, tmp, l);
21 }
22 dst += l;
2423 n -= l;
2524 }
26 wn = ws ? wn - (ws - tmp_ws) : 0;
27 cnt += l;
28 }
29 if (ws) while (n && wn) {
30 l = wcrtomb(s, *ws, 0);
31 if ((l+1)<=1) {
32 if (!l) ws = 0;
33 else cnt = l;
25 if (!*ws) {
26 ws = 0;
3427 break;
3528 }
36 ws++; wn--;
37 /* safe - this loop runs fewer than sizeof(buf) times */
38 s+=l; n-=l;
29 ws++;
30 wn--;
3931 cnt += l;
4032 }
4133 if (dst) *wcs = ws;
lib/libc/musl/src/network/h_errno.c+3-1
......@@ -1,9 +1,11 @@
11#include <netdb.h>
2#include "pthread_impl.h"
23
34#undef h_errno
45int h_errno;
56
67int *__h_errno_location(void)
78{
8 return &h_errno;
9 if (!__pthread_self()->stack) return &h_errno;
10 return &__pthread_self()->h_errno_val;
911}
lib/libc/musl/src/network/herror.c+1-1
......@@ -4,5 +4,5 @@
44
55void herror(const char *msg)
66{
7 fprintf(stderr, "%s%s%s", msg?msg:"", msg?": ":"", hstrerror(h_errno));
7 fprintf(stderr, "%s%s%s\n", msg?msg:"", msg?": ":"", hstrerror(h_errno));
88}
lib/libc/musl/src/network/lookup_name.c+8-3
......@@ -50,7 +50,7 @@ static int name_from_hosts(struct address buf[static MAXADDRS], char canon[stati
5050{
5151 char line[512];
5252 size_t l = strlen(name);
53 int cnt = 0, badfam = 0;
53 int cnt = 0, badfam = 0, have_canon = 0;
5454 unsigned char _buf[1032];
5555 FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
5656 if (!f) switch (errno) {
......@@ -80,14 +80,19 @@ static int name_from_hosts(struct address buf[static MAXADDRS], char canon[stati
8080 continue;
8181 default:
8282 badfam = EAI_NONAME;
83 continue;
83 break;
8484 }
8585
86 if (have_canon) continue;
87
8688 /* Extract first name as canonical name */
8789 for (; *p && isspace(*p); p++);
8890 for (z=p; *z && !isspace(*z); z++);
8991 *z = 0;
90 if (is_valid_hostname(p)) memcpy(canon, p, z-p+1);
92 if (is_valid_hostname(p)) {
93 have_canon = 1;
94 memcpy(canon, p, z-p+1);
95 }
9196 }
9297 __fclose_ca(f);
9398 return cnt ? cnt : badfam;
lib/libc/musl/src/network/res_query.c+15-1
......@@ -1,3 +1,4 @@
1#define _BSD_SOURCE
12#include <resolv.h>
23#include <netdb.h>
34
......@@ -6,7 +7,20 @@ int res_query(const char *name, int class, int type, unsigned char *dest, int le
67 unsigned char q[280];
78 int ql = __res_mkquery(0, name, class, type, 0, 0, 0, q, sizeof q);
89 if (ql < 0) return ql;
9 return __res_send(q, ql, dest, len);
10 int r = __res_send(q, ql, dest, len);
11 if (r<12) {
12 h_errno = TRY_AGAIN;
13 return -1;
14 }
15 if ((dest[3] & 15) == 3) {
16 h_errno = HOST_NOT_FOUND;
17 return -1;
18 }
19 if ((dest[3] & 15) == 0 && !dest[6] && !dest[7]) {
20 h_errno = NO_DATA;
21 return -1;
22 }
23 return r;
1024}
1125
1226weak_alias(res_query, res_search);
lib/libc/musl/src/passwd/getgrouplist.c+2-1
......@@ -31,7 +31,8 @@ int getgrouplist(const char *user, gid_t gid, gid_t *groups, int *ngroups)
3131 if (resp[INITGRFOUND]) {
3232 nscdbuf = calloc(resp[INITGRNGRPS], sizeof(uint32_t));
3333 if (!nscdbuf) goto cleanup;
34 if (!fread(nscdbuf, sizeof(*nscdbuf)*resp[INITGRNGRPS], 1, f)) {
34 size_t nbytes = sizeof(*nscdbuf)*resp[INITGRNGRPS];
35 if (nbytes && !fread(nscdbuf, nbytes, 1, f)) {
3536 if (!ferror(f)) errno = EIO;
3637 goto cleanup;
3738 }
lib/libc/musl/src/prng/random.c+2
......@@ -1,6 +1,7 @@
11#include <stdlib.h>
22#include <stdint.h>
33#include "lock.h"
4#include "fork_impl.h"
45
56/*
67this code uses the same lagged fibonacci generator as the
......@@ -23,6 +24,7 @@ static int i = 3;
2324static int j = 0;
2425static uint32_t *x = init+1;
2526static volatile int lock[1];
27volatile int *const __random_lockptr = lock;
2628
2729static uint32_t lcg31(uint32_t x) {
2830 return (1103515245*x + 12345) & 0x7fffffff;
lib/libc/musl/src/process/_Fork.c created+38
......@@ -0,0 +1,38 @@
1#include <unistd.h>
2#include <signal.h>
3#include "syscall.h"
4#include "libc.h"
5#include "lock.h"
6#include "pthread_impl.h"
7#include "aio_impl.h"
8
9static void dummy(int x) { }
10weak_alias(dummy, __aio_atfork);
11
12pid_t _Fork(void)
13{
14 pid_t ret;
15 sigset_t set;
16 __block_all_sigs(&set);
17 __aio_atfork(-1);
18 LOCK(__abort_lock);
19#ifdef SYS_fork
20 ret = __syscall(SYS_fork);
21#else
22 ret = __syscall(SYS_clone, SIGCHLD, 0);
23#endif
24 if (!ret) {
25 pthread_t self = __pthread_self();
26 self->tid = __syscall(SYS_gettid);
27 self->robust_list.off = 0;
28 self->robust_list.pending = 0;
29 self->next = self->prev = self;
30 __thread_list_lock = 0;
31 libc.threads_minus_1 = 0;
32 if (libc.need_locks) libc.need_locks = -1;
33 }
34 UNLOCK(__abort_lock);
35 __aio_atfork(!ret);
36 __restore_sigs(&set);
37 return __syscall_ret(ret);
38}
lib/libc/musl/src/process/fork.c+71-23
......@@ -1,38 +1,86 @@
11#include <unistd.h>
2#include <string.h>
3#include <signal.h>
4#include "syscall.h"
2#include <errno.h>
53#include "libc.h"
4#include "lock.h"
65#include "pthread_impl.h"
6#include "fork_impl.h"
77
8static void dummy(int x)
9{
10}
8static volatile int *const dummy_lockptr = 0;
9
10weak_alias(dummy_lockptr, __at_quick_exit_lockptr);
11weak_alias(dummy_lockptr, __atexit_lockptr);
12weak_alias(dummy_lockptr, __dlerror_lockptr);
13weak_alias(dummy_lockptr, __gettext_lockptr);
14weak_alias(dummy_lockptr, __locale_lockptr);
15weak_alias(dummy_lockptr, __random_lockptr);
16weak_alias(dummy_lockptr, __sem_open_lockptr);
17weak_alias(dummy_lockptr, __stdio_ofl_lockptr);
18weak_alias(dummy_lockptr, __syslog_lockptr);
19weak_alias(dummy_lockptr, __timezone_lockptr);
20weak_alias(dummy_lockptr, __bump_lockptr);
21
22weak_alias(dummy_lockptr, __vmlock_lockptr);
1123
24static volatile int *const *const atfork_locks[] = {
25 &__at_quick_exit_lockptr,
26 &__atexit_lockptr,
27 &__dlerror_lockptr,
28 &__gettext_lockptr,
29 &__locale_lockptr,
30 &__random_lockptr,
31 &__sem_open_lockptr,
32 &__stdio_ofl_lockptr,
33 &__syslog_lockptr,
34 &__timezone_lockptr,
35 &__bump_lockptr,
36};
37
38static void dummy(int x) { }
1239weak_alias(dummy, __fork_handler);
40weak_alias(dummy, __malloc_atfork);
41weak_alias(dummy, __ldso_atfork);
42
43static void dummy_0(void) { }
44weak_alias(dummy_0, __tl_lock);
45weak_alias(dummy_0, __tl_unlock);
1346
1447pid_t fork(void)
1548{
16 pid_t ret;
1749 sigset_t set;
1850 __fork_handler(-1);
19 __block_all_sigs(&set);
20#ifdef SYS_fork
21 ret = __syscall(SYS_fork);
22#else
23 ret = __syscall(SYS_clone, SIGCHLD, 0);
24#endif
25 if (!ret) {
26 pthread_t self = __pthread_self();
27 self->tid = __syscall(SYS_gettid);
28 self->robust_list.off = 0;
29 self->robust_list.pending = 0;
30 self->next = self->prev = self;
31 __thread_list_lock = 0;
32 libc.threads_minus_1 = 0;
33 if (libc.need_locks) libc.need_locks = -1;
51 __block_app_sigs(&set);
52 int need_locks = libc.need_locks > 0;
53 if (need_locks) {
54 __ldso_atfork(-1);
55 __inhibit_ptc();
56 for (int i=0; i<sizeof atfork_locks/sizeof *atfork_locks; i++)
57 if (*atfork_locks[i]) LOCK(*atfork_locks[i]);
58 __malloc_atfork(-1);
59 __tl_lock();
60 }
61 pthread_t self=__pthread_self(), next=self->next;
62 pid_t ret = _Fork();
63 int errno_save = errno;
64 if (need_locks) {
65 if (!ret) {
66 for (pthread_t td=next; td!=self; td=td->next)
67 td->tid = -1;
68 if (__vmlock_lockptr) {
69 __vmlock_lockptr[0] = 0;
70 __vmlock_lockptr[1] = 0;
71 }
72 }
73 __tl_unlock();
74 __malloc_atfork(!ret);
75 for (int i=0; i<sizeof atfork_locks/sizeof *atfork_locks; i++)
76 if (*atfork_locks[i])
77 if (ret) UNLOCK(*atfork_locks[i]);
78 else **atfork_locks[i] = 0;
79 __release_ptc();
80 __ldso_atfork(!ret);
3481 }
3582 __restore_sigs(&set);
3683 __fork_handler(!ret);
37 return __syscall_ret(ret);
84 if (ret<0) errno = errno_save;
85 return ret;
3886}
lib/libc/musl/src/process/posix_spawn.c+13-3
......@@ -6,6 +6,7 @@
66#include <fcntl.h>
77#include <sys/wait.h>
88#include "syscall.h"
9#include "lock.h"
910#include "pthread_impl.h"
1011#include "fdop.h"
1112
......@@ -170,9 +171,6 @@ int posix_spawn(pid_t *restrict res, const char *restrict path,
170171 int ec=0, cs;
171172 struct args args;
172173
173 if (pipe2(args.p, O_CLOEXEC))
174 return errno;
175
176174 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
177175
178176 args.path = path;
......@@ -182,9 +180,20 @@ int posix_spawn(pid_t *restrict res, const char *restrict path,
182180 args.envp = envp;
183181 pthread_sigmask(SIG_BLOCK, SIGALL_SET, &args.oldmask);
184182
183 /* The lock guards both against seeing a SIGABRT disposition change
184 * by abort and against leaking the pipe fd to fork-without-exec. */
185 LOCK(__abort_lock);
186
187 if (pipe2(args.p, O_CLOEXEC)) {
188 UNLOCK(__abort_lock);
189 ec = errno;
190 goto fail;
191 }
192
185193 pid = __clone(child, stack+sizeof stack,
186194 CLONE_VM|CLONE_VFORK|SIGCHLD, &args);
187195 close(args.p[1]);
196 UNLOCK(__abort_lock);
188197
189198 if (pid > 0) {
190199 if (read(args.p[0], &ec, sizeof ec) != sizeof ec) ec = 0;
......@@ -197,6 +206,7 @@ int posix_spawn(pid_t *restrict res, const char *restrict path,
197206
198207 if (!ec && res) *res = pid;
199208
209fail:
200210 pthread_sigmask(SIG_SETMASK, &args.oldmask, 0);
201211 pthread_setcancelstate(cs, 0);
202212
lib/libc/musl/src/setjmp/aarch64/longjmp.s+3-4
......@@ -18,7 +18,6 @@ longjmp:
1818 ldp d12, d13, [x0,#144]
1919 ldp d14, d15, [x0,#160]
2020
21 mov x0, x1
22 cbnz x1, 1f
23 mov x0, #1
241: br x30
21 cmp w1, 0
22 csinc w0, w1, wzr, ne
23 br x30
lib/libc/musl/src/setjmp/i386/longjmp.s+4-8
......@@ -6,15 +6,11 @@ _longjmp:
66longjmp:
77 mov 4(%esp),%edx
88 mov 8(%esp),%eax
9 test %eax,%eax
10 jnz 1f
11 inc %eax
121:
9 cmp $1,%eax
10 adc $0, %al
1311 mov (%edx),%ebx
1412 mov 4(%edx),%esi
1513 mov 8(%edx),%edi
1614 mov 12(%edx),%ebp
17 mov 16(%edx),%ecx
18 mov %ecx,%esp
19 mov 20(%edx),%ecx
20 jmp *%ecx
15 mov 16(%edx),%esp
16 jmp *20(%edx)
lib/libc/musl/src/setjmp/x32/longjmp.s+5-9
......@@ -5,18 +5,14 @@
55.type longjmp,@function
66_longjmp:
77longjmp:
8 mov %rsi,%rax /* val will be longjmp return */
9 test %rax,%rax
10 jnz 1f
11 inc %rax /* if val==0, val=1 per longjmp semantics */
121:
8 xor %eax,%eax
9 cmp $1,%esi /* CF = val ? 0 : 1 */
10 adc %esi,%eax /* eax = val + !val */
1311 mov (%rdi),%rbx /* rdi is the jmp_buf, restore regs from it */
1412 mov 8(%rdi),%rbp
1513 mov 16(%rdi),%r12
1614 mov 24(%rdi),%r13
1715 mov 32(%rdi),%r14
1816 mov 40(%rdi),%r15
19 mov 48(%rdi),%rdx /* this ends up being the stack pointer */
20 mov %rdx,%rsp
21 mov 56(%rdi),%rdx /* this is the instruction pointer */
22 jmp *%rdx /* goto saved address without altering rsp */
17 mov 48(%rdi),%rsp
18 jmp *56(%rdi) /* goto saved address without altering rsp */
lib/libc/musl/src/setjmp/x32/setjmp.s+1-1
......@@ -18,5 +18,5 @@ setjmp:
1818 mov %rdx,48(%rdi)
1919 mov (%rsp),%rdx /* save return addr ptr for new rip */
2020 mov %rdx,56(%rdi)
21 xor %rax,%rax /* always return 0 */
21 xor %eax,%eax /* always return 0 */
2222 ret
lib/libc/musl/src/setjmp/x86_64/longjmp.s+5-9
......@@ -5,18 +5,14 @@
55.type longjmp,@function
66_longjmp:
77longjmp:
8 mov %rsi,%rax /* val will be longjmp return */
9 test %rax,%rax
10 jnz 1f
11 inc %rax /* if val==0, val=1 per longjmp semantics */
121:
8 xor %eax,%eax
9 cmp $1,%esi /* CF = val ? 0 : 1 */
10 adc %esi,%eax /* eax = val + !val */
1311 mov (%rdi),%rbx /* rdi is the jmp_buf, restore regs from it */
1412 mov 8(%rdi),%rbp
1513 mov 16(%rdi),%r12
1614 mov 24(%rdi),%r13
1715 mov 32(%rdi),%r14
1816 mov 40(%rdi),%r15
19 mov 48(%rdi),%rdx /* this ends up being the stack pointer */
20 mov %rdx,%rsp
21 mov 56(%rdi),%rdx /* this is the instruction pointer */
22 jmp *%rdx /* goto saved address without altering rsp */
17 mov 48(%rdi),%rsp
18 jmp *56(%rdi) /* goto saved address without altering rsp */
lib/libc/musl/src/setjmp/x86_64/setjmp.s+1-1
......@@ -18,5 +18,5 @@ setjmp:
1818 mov %rdx,48(%rdi)
1919 mov (%rsp),%rdx /* save return addr ptr for new rip */
2020 mov %rdx,56(%rdi)
21 xor %rax,%rax /* always return 0 */
21 xor %eax,%eax /* always return 0 */
2222 ret
lib/libc/musl/src/signal/sigaction.c+16-20
......@@ -7,12 +7,6 @@
77#include "lock.h"
88#include "ksigaction.h"
99
10static volatile int dummy_lock[1] = { 0 };
11
12extern hidden volatile int __abort_lock[1];
13
14weak_alias(dummy_lock, __abort_lock);
15
1610static int unmask_done;
1711static unsigned long handler_set[_NSIG/(8*sizeof(long))];
1812
......@@ -26,7 +20,6 @@ volatile int __eintr_valid_flag;
2620int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
2721{
2822 struct k_sigaction ksa, ksa_old;
29 unsigned long set[_NSIG/(8*sizeof(long))];
3023 if (sa) {
3124 if ((uintptr_t)sa->sa_handler > 1UL) {
3225 a_or_l(handler_set+(sig-1)/(8*sizeof(long)),
......@@ -50,24 +43,12 @@ int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigact
5043 a_store(&__eintr_valid_flag, 1);
5144 }
5245 }
53 /* Changing the disposition of SIGABRT to anything but
54 * SIG_DFL requires a lock, so that it cannot be changed
55 * while abort is terminating the process after simply
56 * calling raise(SIGABRT) failed to do so. */
57 if (sa->sa_handler != SIG_DFL && sig == SIGABRT) {
58 __block_all_sigs(&set);
59 LOCK(__abort_lock);
60 }
6146 ksa.handler = sa->sa_handler;
6247 ksa.flags = sa->sa_flags | SA_RESTORER;
6348 ksa.restorer = (sa->sa_flags & SA_SIGINFO) ? __restore_rt : __restore;
6449 memcpy(&ksa.mask, &sa->sa_mask, _NSIG/8);
6550 }
6651 int r = __syscall(SYS_rt_sigaction, sig, sa?&ksa:0, old?&ksa_old:0, _NSIG/8);
67 if (sig == SIGABRT && sa && sa->sa_handler != SIG_DFL) {
68 UNLOCK(__abort_lock);
69 __restore_sigs(&set);
70 }
7152 if (old && !r) {
7253 old->sa_handler = ksa_old.handler;
7354 old->sa_flags = ksa_old.flags;
......@@ -78,11 +59,26 @@ int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigact
7859
7960int __sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
8061{
62 unsigned long set[_NSIG/(8*sizeof(long))];
63
8164 if (sig-32U < 3 || sig-1U >= _NSIG-1) {
8265 errno = EINVAL;
8366 return -1;
8467 }
85 return __libc_sigaction(sig, sa, old);
68
69 /* Doing anything with the disposition of SIGABRT requires a lock,
70 * so that it cannot be changed while abort is terminating the
71 * process and so any change made by abort can't be observed. */
72 if (sig == SIGABRT) {
73 __block_all_sigs(&set);
74 LOCK(__abort_lock);
75 }
76 int r = __libc_sigaction(sig, sa, old);
77 if (sig == SIGABRT) {
78 UNLOCK(__abort_lock);
79 __restore_sigs(&set);
80 }
81 return r;
8682}
8783
8884weak_alias(__sigaction, sigaction);
lib/libc/musl/src/stdio/__stdio_close.c+1
......@@ -1,4 +1,5 @@
11#include "stdio_impl.h"
2#include "aio_impl.h"
23
34static int dummy(int fd)
45{
lib/libc/musl/src/stdio/ofl.c+2
......@@ -1,8 +1,10 @@
11#include "stdio_impl.h"
22#include "lock.h"
3#include "fork_impl.h"
34
45static FILE *ofl_head;
56static volatile int ofl_lock[1];
7volatile int *const __stdio_ofl_lockptr = ofl_lock;
68
79FILE **__ofl_lock()
810{
lib/libc/musl/src/string/strstr.c+1-1
......@@ -96,7 +96,7 @@ static char *twoway_strstr(const unsigned char *h, const unsigned char *n)
9696 for (;;) {
9797 /* Update incremental end-of-haystack pointer */
9898 if (z-h < l) {
99 /* Fast estimate for MIN(l,63) */
99 /* Fast estimate for MAX(l,63) */
100100 size_t grow = l | 63;
101101 const unsigned char *z2 = memchr(z, 0, grow);
102102 if (z2) {
lib/libc/musl/src/termios/tcgetwinsize.c created+8
......@@ -0,0 +1,8 @@
1#include <termios.h>
2#include <sys/ioctl.h>
3#include "syscall.h"
4
5int tcgetwinsize(int fd, struct winsize *wsz)
6{
7 return syscall(SYS_ioctl, fd, TIOCGWINSZ, wsz);
8}
lib/libc/musl/src/termios/tcsetwinsize.c created+8
......@@ -0,0 +1,8 @@
1#include <termios.h>
2#include <sys/ioctl.h>
3#include "syscall.h"
4
5int tcsetwinsize(int fd, const struct winsize *wsz)
6{
7 return syscall(SYS_ioctl, fd, TIOCSWINSZ, wsz);
8}
lib/libc/musl/src/thread/i386/__set_thread_area.s+1
......@@ -28,6 +28,7 @@ __set_thread_area:
2828 ret
29292:
3030 mov %ebx,%ecx
31 xor %eax,%eax
3132 xor %ebx,%ebx
3233 xor %edx,%edx
3334 mov %ebx,(%esp)
lib/libc/musl/src/thread/pthread_attr_get.c+1-1
......@@ -70,7 +70,7 @@ int pthread_condattr_getpshared(const pthread_condattr_t *restrict a, int *restr
7070
7171int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *restrict a, int *restrict protocol)
7272{
73 *protocol = PTHREAD_PRIO_NONE;
73 *protocol = a->__attr / 8U % 2;
7474 return 0;
7575}
7676int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict a, int *restrict pshared)
lib/libc/musl/src/thread/pthread_cond_timedwait.c+9-5
......@@ -146,14 +146,18 @@ relock:
146146
147147 if (oldstate == WAITING) goto done;
148148
149 if (!node.next) a_inc(&m->_m_waiters);
149 if (!node.next && !(m->_m_type & 8))
150 a_inc(&m->_m_waiters);
150151
151152 /* Unlock the barrier that's holding back the next waiter, and
152153 * either wake it or requeue it to the mutex. */
153 if (node.prev)
154 unlock_requeue(&node.prev->barrier, &m->_m_lock, m->_m_type & 128);
155 else
156 a_dec(&m->_m_waiters);
154 if (node.prev) {
155 int val = m->_m_lock;
156 if (val>0) a_cas(&m->_m_lock, val, val|0x80000000);
157 unlock_requeue(&node.prev->barrier, &m->_m_lock, m->_m_type & (8|128));
158 } else if (!(m->_m_type & 8)) {
159 a_dec(&m->_m_waiters);
160 }
157161
158162 /* Since a signal was consumed, cancellation is not permitted. */
159163 if (e == ECANCELED) e = 0;
lib/libc/musl/src/thread/pthread_create.c+17-10
......@@ -69,12 +69,25 @@ _Noreturn void __pthread_exit(void *result)
6969
7070 __pthread_tsd_run_dtors();
7171
72 __block_app_sigs(&set);
73
74 /* This atomic potentially competes with a concurrent pthread_detach
75 * call; the loser is responsible for freeing thread resources. */
76 int state = a_cas(&self->detach_state, DT_JOINABLE, DT_EXITING);
77
78 if (state==DT_DETACHED && self->map_base) {
79 /* Since __unmapself bypasses the normal munmap code path,
80 * explicitly wait for vmlock holders first. This must be
81 * done before any locks are taken, to avoid lock ordering
82 * issues that could lead to deadlock. */
83 __vm_wait();
84 }
85
7286 /* Access to target the exiting thread with syscalls that use
7387 * its kernel tid is controlled by killlock. For detached threads,
7488 * any use past this point would have undefined behavior, but for
7589 * joinable threads it's a valid usage that must be handled.
7690 * Signals must be blocked since pthread_kill must be AS-safe. */
77 __block_app_sigs(&set);
7891 LOCK(self->killlock);
7992
8093 /* The thread list lock must be AS-safe, and thus depends on
......@@ -87,6 +100,7 @@ _Noreturn void __pthread_exit(void *result)
87100 if (self->next == self) {
88101 __tl_unlock();
89102 UNLOCK(self->killlock);
103 self->detach_state = state;
90104 __restore_sigs(&set);
91105 exit(0);
92106 }
......@@ -125,10 +139,6 @@ _Noreturn void __pthread_exit(void *result)
125139 self->prev->next = self->next;
126140 self->prev = self->next = self;
127141
128 /* This atomic potentially competes with a concurrent pthread_detach
129 * call; the loser is responsible for freeing thread resources. */
130 int state = a_cas(&self->detach_state, DT_JOINABLE, DT_EXITING);
131
132142 if (state==DT_DETACHED && self->map_base) {
133143 /* Detached threads must block even implementation-internal
134144 * signals, since they will not have a stack in their last
......@@ -140,16 +150,13 @@ _Noreturn void __pthread_exit(void *result)
140150 if (self->robust_list.off)
141151 __syscall(SYS_set_robust_list, 0, 3*sizeof(long));
142152
143 /* Since __unmapself bypasses the normal munmap code path,
144 * explicitly wait for vmlock holders first. */
145 __vm_wait();
146
147153 /* The following call unmaps the thread's stack mapping
148154 * and then exits without touching the stack. */
149155 __unmapself(self->map_base, self->map_size);
150156 }
151157
152158 /* Wake any joiner. */
159 a_store(&self->detach_state, DT_EXITED);
153160 __wake(&self->detach_state, 1, 1);
154161
155162 /* After the kernel thread exits, its tid may be reused. Clear it
......@@ -314,7 +321,7 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att
314321 new->detach_state = DT_JOINABLE;
315322 }
316323 new->robust_list.head = &new->robust_list.head;
317 new->CANARY = self->CANARY;
324 new->canary = self->canary;
318325 new->sysinfo = self->sysinfo;
319326
320327 /* Setup argument structure for the new thread on its stack.
lib/libc/musl/src/thread/pthread_mutex_destroy.c+5-1
......@@ -1,6 +1,10 @@
1#include <pthread.h>
1#include "pthread_impl.h"
22
33int pthread_mutex_destroy(pthread_mutex_t *mutex)
44{
5 /* If the mutex being destroyed is process-shared and has nontrivial
6 * type (tracking ownership), it might be in the pending slot of a
7 * robust_list; wait for quiescence. */
8 if (mutex->_m_type > 128) __vm_wait();
59 return 0;
610}
lib/libc/musl/src/thread/pthread_mutexattr_setprotocol.c+9-10
......@@ -1,24 +1,23 @@
11#include "pthread_impl.h"
22#include "syscall.h"
33
4static pthread_once_t check_pi_once;
5static int check_pi_result;
6
7static void check_pi()
8{
9 volatile int lk = 0;
10 check_pi_result = -__syscall(SYS_futex, &lk, FUTEX_LOCK_PI, 0, 0);
11}
4static volatile int check_pi_result = -1;
125
136int pthread_mutexattr_setprotocol(pthread_mutexattr_t *a, int protocol)
147{
8 int r;
159 switch (protocol) {
1610 case PTHREAD_PRIO_NONE:
1711 a->__attr &= ~8;
1812 return 0;
1913 case PTHREAD_PRIO_INHERIT:
20 pthread_once(&check_pi_once, check_pi);
21 if (check_pi_result) return check_pi_result;
14 r = check_pi_result;
15 if (r < 0) {
16 volatile int lk = 0;
17 r = -__syscall(SYS_futex, &lk, FUTEX_LOCK_PI, 0, 0);
18 a_store(&check_pi_result, r);
19 }
20 if (r) return r;
2221 a->__attr |= 8;
2322 return 0;
2423 case PTHREAD_PRIO_PROTECT:
lib/libc/musl/src/thread/pthread_mutexattr_setrobust.c+9-11
......@@ -1,22 +1,20 @@
11#include "pthread_impl.h"
22#include "syscall.h"
33
4static pthread_once_t check_robust_once;
5static int check_robust_result;
6
7static void check_robust()
8{
9 void *p;
10 size_t l;
11 check_robust_result = -__syscall(SYS_get_robust_list, 0, &p, &l);
12}
4static volatile int check_robust_result = -1;
135
146int pthread_mutexattr_setrobust(pthread_mutexattr_t *a, int robust)
157{
168 if (robust > 1U) return EINVAL;
179 if (robust) {
18 pthread_once(&check_robust_once, check_robust);
19 if (check_robust_result) return check_robust_result;
10 int r = check_robust_result;
11 if (r < 0) {
12 void *p;
13 size_t l;
14 r = -__syscall(SYS_get_robust_list, 0, &p, &l);
15 a_store(&check_robust_result, r);
16 }
17 if (r) return r;
2018 a->__attr |= 4;
2119 return 0;
2220 }
lib/libc/musl/src/thread/s390x/clone.s+6
......@@ -17,6 +17,9 @@ __clone:
1717 # if (!tid) syscall(SYS_exit, a(d));
1818 # return tid;
1919
20 # preserve call-saved register used as syscall arg
21 stg %r6, 48(%r15)
22
2023 # create initial stack frame for new thread
2124 nill %r3, 0xfff8
2225 aghi %r3, -160
......@@ -35,6 +38,9 @@ __clone:
3538 lg %r6, 160(%r15)
3639 svc 120
3740
41 # restore call-saved register
42 lg %r6, 48(%r15)
43
3844 # if error or if we're the parent, return
3945 ltgr %r2, %r2
4046 bnzr %r14
lib/libc/musl/src/thread/s390x/syscall_cp.s+2
......@@ -14,6 +14,7 @@ __cp_begin:
1414 icm %r2, 15, 0(%r2)
1515 jne __cp_cancel
1616
17 stg %r6, 48(%r15)
1718 stg %r7, 56(%r15)
1819 lgr %r1, %r3
1920 lgr %r2, %r4
......@@ -26,6 +27,7 @@ __cp_begin:
2627
2728__cp_end:
2829 lg %r7, 56(%r15)
30 lg %r6, 48(%r15)
2931 br %r14
3032
3133__cp_cancel:
lib/libc/musl/src/thread/sem_open.c+12-3
......@@ -12,6 +12,12 @@
1212#include <stdlib.h>
1313#include <pthread.h>
1414#include "lock.h"
15#include "fork_impl.h"
16
17#define malloc __libc_malloc
18#define calloc __libc_calloc
19#define realloc undef
20#define free undef
1521
1622static struct {
1723 ino_t ino;
......@@ -19,6 +25,7 @@ static struct {
1925 int refcnt;
2026} *semtab;
2127static volatile int lock[1];
28volatile int *const __sem_open_lockptr = lock;
2229
2330#define FLAGS (O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NONBLOCK)
2431
......@@ -163,10 +170,12 @@ int sem_close(sem_t *sem)
163170 int i;
164171 LOCK(lock);
165172 for (i=0; i<SEM_NSEMS_MAX && semtab[i].sem != sem; i++);
166 if (!--semtab[i].refcnt) {
167 semtab[i].sem = 0;
168 semtab[i].ino = 0;
173 if (--semtab[i].refcnt) {
174 UNLOCK(lock);
175 return 0;
169176 }
177 semtab[i].sem = 0;
178 semtab[i].ino = 0;
170179 UNLOCK(lock);
171180 munmap(sem, sizeof *sem);
172181 return 0;
lib/libc/musl/src/thread/synccall.c+2-1
......@@ -63,7 +63,8 @@ void __synccall(void (*func)(void *), void *ctx)
6363 sem_init(&target_sem, 0, 0);
6464 sem_init(&caller_sem, 0, 0);
6565
66 if (!libc.threads_minus_1) goto single_threaded;
66 if (!libc.threads_minus_1 || __syscall(SYS_gettid) != self->tid)
67 goto single_threaded;
6768
6869 callback = func;
6970 context = ctx;
lib/libc/musl/src/thread/vmlock.c+2
......@@ -1,6 +1,8 @@
11#include "pthread_impl.h"
2#include "fork_impl.h"
23
34static volatile int vmlock[2];
5volatile int *const __vmlock_lockptr = vmlock;
46
57void __vm_wait()
68{
lib/libc/musl/src/time/__tz.c+8-1
......@@ -6,6 +6,12 @@
66#include <sys/mman.h>
77#include "libc.h"
88#include "lock.h"
9#include "fork_impl.h"
10
11#define malloc __libc_malloc
12#define calloc undef
13#define realloc undef
14#define free undef
915
1016long __timezone = 0;
1117int __daylight = 0;
......@@ -30,6 +36,7 @@ static char *old_tz = old_tz_buf;
3036static size_t old_tz_size = sizeof old_tz_buf;
3137
3238static volatile int lock[1];
39volatile int *const __timezone_lockptr = lock;
3340
3441static int getint(const char **p)
3542{
......@@ -178,7 +185,7 @@ static void do_tzset()
178185 zi = map;
179186 if (map) {
180187 int scale = 2;
181 if (sizeof(time_t) > 4 && map[4]=='2') {
188 if (map[4]!='1') {
182189 size_t skip = zi_dotprod(zi+20, VEC(1,1,8,5,6,1), 6);
183190 trans = zi+skip+44+44;
184191 scale++;
lib/libc/musl/src/time/timer_create.c+13-17
......@@ -2,6 +2,7 @@
22#include <setjmp.h>
33#include <limits.h>
44#include "pthread_impl.h"
5#include "atomic.h"
56
67struct ksigevent {
78 union sigval sigev_value;
......@@ -32,19 +33,6 @@ static void cleanup_fromsig(void *p)
3233 longjmp(p, 1);
3334}
3435
35static void timer_handler(int sig, siginfo_t *si, void *ctx)
36{
37}
38
39static void install_handler()
40{
41 struct sigaction sa = {
42 .sa_sigaction = timer_handler,
43 .sa_flags = SA_SIGINFO | SA_RESTART
44 };
45 __libc_sigaction(SIGTIMER, &sa, 0);
46}
47
4836static void *start(void *arg)
4937{
5038 pthread_t self = __pthread_self();
......@@ -71,7 +59,7 @@ static void *start(void *arg)
7159
7260int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict res)
7361{
74 static pthread_once_t once = PTHREAD_ONCE_INIT;
62 volatile static int init = 0;
7563 pthread_t td;
7664 pthread_attr_t attr;
7765 int r;
......@@ -83,11 +71,15 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict
8371 switch (evp ? evp->sigev_notify : SIGEV_SIGNAL) {
8472 case SIGEV_NONE:
8573 case SIGEV_SIGNAL:
74 case SIGEV_THREAD_ID:
8675 if (evp) {
8776 ksev.sigev_value = evp->sigev_value;
8877 ksev.sigev_signo = evp->sigev_signo;
8978 ksev.sigev_notify = evp->sigev_notify;
90 ksev.sigev_tid = 0;
79 if (evp->sigev_notify == SIGEV_THREAD_ID)
80 ksev.sigev_tid = evp->sigev_notify_thread_id;
81 else
82 ksev.sigev_tid = 0;
9183 ksevp = &ksev;
9284 }
9385 if (syscall(SYS_timer_create, clk, ksevp, &timerid) < 0)
......@@ -95,7 +87,11 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict
9587 *res = (void *)(intptr_t)timerid;
9688 break;
9789 case SIGEV_THREAD:
98 pthread_once(&once, install_handler);
90 if (!init) {
91 struct sigaction sa = { .sa_handler = SIG_DFL };
92 __libc_sigaction(SIGTIMER, &sa, 0);
93 a_store(&init, 1);
94 }
9995 if (evp->sigev_notify_attributes)
10096 attr = *evp->sigev_notify_attributes;
10197 else
......@@ -115,7 +111,7 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict
115111
116112 ksev.sigev_value.sival_ptr = 0;
117113 ksev.sigev_signo = SIGTIMER;
118 ksev.sigev_notify = 4; /* SIGEV_THREAD_ID */
114 ksev.sigev_notify = SIGEV_THREAD_ID;
119115 ksev.sigev_tid = td->tid;
120116 if (syscall(SYS_timer_create, clk, &ksev, &timerid) < 0)
121117 timerid = -1;
lib/libc/musl/src/unistd/close.c+1
......@@ -1,5 +1,6 @@
11#include <unistd.h>
22#include <errno.h>
3#include "aio_impl.h"
34#include "syscall.h"
45
56static int dummy(int fd)
lib/libc/musl/src/unistd/faccessat.c+8-3
......@@ -25,12 +25,17 @@ static int checker(void *p)
2525
2626int faccessat(int fd, const char *filename, int amode, int flag)
2727{
28 if (!flag || (flag==AT_EACCESS && getuid()==geteuid() && getgid()==getegid()))
29 return syscall(SYS_faccessat, fd, filename, amode, flag);
28 if (flag) {
29 int ret = __syscall(SYS_faccessat2, fd, filename, amode, flag);
30 if (ret != -ENOSYS) return __syscall_ret(ret);
31 }
3032
31 if (flag != AT_EACCESS)
33 if (flag & ~AT_EACCESS)
3234 return __syscall_ret(-EINVAL);
3335
36 if (!flag || (getuid()==geteuid() && getgid()==getegid()))
37 return syscall(SYS_faccessat, fd, filename, amode);
38
3439 char stack[1024];
3540 sigset_t set;
3641 pid_t pid;
lib/libc/musl/src/unistd/readlink.c+9-2
......@@ -4,9 +4,16 @@
44
55ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize)
66{
7 char dummy[1];
8 if (!bufsize) {
9 buf = dummy;
10 bufsize = 1;
11 }
712#ifdef SYS_readlink
8 return syscall(SYS_readlink, path, buf, bufsize);
13 int r = __syscall(SYS_readlink, path, buf, bufsize);
914#else
10 return syscall(SYS_readlinkat, AT_FDCWD, path, buf, bufsize);
15 int r = __syscall(SYS_readlinkat, AT_FDCWD, path, buf, bufsize);
1116#endif
17 if (buf == dummy && r > 0) r = 0;
18 return __syscall_ret(r);
1219}
lib/libc/musl/src/unistd/readlinkat.c+8-1
......@@ -3,5 +3,12 @@
33
44ssize_t readlinkat(int fd, const char *restrict path, char *restrict buf, size_t bufsize)
55{
6 return syscall(SYS_readlinkat, fd, path, buf, bufsize);
6 char dummy[1];
7 if (!bufsize) {
8 buf = dummy;
9 bufsize = 1;
10 }
11 int r = __syscall(SYS_readlinkat, fd, path, buf, bufsize);
12 if (buf == dummy && r > 0) r = 0;
13 return __syscall_ret(r);
714}
lib/libc/musl/src/unistd/setxid.c+9-14
......@@ -1,20 +1,19 @@
11#include <unistd.h>
2#include <errno.h>
2#include <signal.h>
33#include "syscall.h"
44#include "libc.h"
5#include "pthread_impl.h"
65
76struct ctx {
87 int id, eid, sid;
9 int nr, err;
8 int nr, ret;
109};
1110
1211static void do_setxid(void *p)
1312{
1413 struct ctx *c = p;
15 if (c->err>0) return;
16 int ret = -__syscall(c->nr, c->id, c->eid, c->sid);
17 if (ret && !c->err) {
14 if (c->ret<0) return;
15 int ret = __syscall(c->nr, c->id, c->eid, c->sid);
16 if (ret && !c->ret) {
1817 /* If one thread fails to set ids after another has already
1918 * succeeded, forcibly killing the process is the only safe
2019 * thing to do. State is inconsistent and dangerous. Use
......@@ -22,18 +21,14 @@ static void do_setxid(void *p)
2221 __block_all_sigs(0);
2322 __syscall(SYS_kill, __syscall(SYS_getpid), SIGKILL);
2423 }
25 c->err = ret;
24 c->ret = ret;
2625}
2726
2827int __setxid(int nr, int id, int eid, int sid)
2928{
30 /* err is initially nonzero so that failure of the first thread does not
29 /* ret is initially nonzero so that failure of the first thread does not
3130 * trigger the safety kill above. */
32 struct ctx c = { .nr = nr, .id = id, .eid = eid, .sid = sid, .err = -1 };
31 struct ctx c = { .nr = nr, .id = id, .eid = eid, .sid = sid, .ret = 1 };
3332 __synccall(do_setxid, &c);
34 if (c.err) {
35 if (c.err>0) errno = c.err;
36 return -1;
37 }
38 return 0;
33 return __syscall_ret(c.ret);
3934}
src/musl.zig+14
......@@ -522,6 +522,7 @@ const src_files = [_][]const u8{
522522 "musl/src/errno/strerror.c",
523523 "musl/src/exit/_Exit.c",
524524 "musl/src/exit/abort.c",
525 "musl/src/exit/abort_lock.c",
525526 "musl/src/exit/arm/__aeabi_atexit.c",
526527 "musl/src/exit/assert.c",
527528 "musl/src/exit/at_quick_exit.c",
......@@ -658,6 +659,7 @@ const src_files = [_][]const u8{
658659 "musl/src/linux/flock.c",
659660 "musl/src/linux/getdents.c",
660661 "musl/src/linux/getrandom.c",
662 "musl/src/linux/gettid.c",
661663 "musl/src/linux/inotify.c",
662664 "musl/src/linux/ioperm.c",
663665 "musl/src/linux/iopl.c",
......@@ -731,6 +733,8 @@ const src_files = [_][]const u8{
731733 "musl/src/locale/wcscoll.c",
732734 "musl/src/locale/wcsxfrm.c",
733735 "musl/src/malloc/calloc.c",
736 "musl/src/malloc/free.c",
737 "musl/src/malloc/libc_calloc.c",
734738 "musl/src/malloc/lite_malloc.c",
735739 "musl/src/malloc/mallocng/aligned_alloc.c",
736740 "musl/src/malloc/mallocng/donate.c",
......@@ -739,7 +743,12 @@ const src_files = [_][]const u8{
739743 "musl/src/malloc/mallocng/malloc_usable_size.c",
740744 "musl/src/malloc/mallocng/realloc.c",
741745 "musl/src/malloc/memalign.c",
746 "musl/src/malloc/oldmalloc/aligned_alloc.c",
747 "musl/src/malloc/oldmalloc/malloc.c",
748 "musl/src/malloc/oldmalloc/malloc_usable_size.c",
742749 "musl/src/malloc/posix_memalign.c",
750 "musl/src/malloc/realloc.c",
751 "musl/src/malloc/reallocarray.c",
743752 "musl/src/malloc/replaced.c",
744753 "musl/src/math/__cos.c",
745754 "musl/src/math/__cosdf.c",
......@@ -754,6 +763,7 @@ const src_files = [_][]const u8{
754763 "musl/src/math/__math_divzerof.c",
755764 "musl/src/math/__math_invalid.c",
756765 "musl/src/math/__math_invalidf.c",
766 "musl/src/math/__math_invalidl.c",
757767 "musl/src/math/__math_oflow.c",
758768 "musl/src/math/__math_oflowf.c",
759769 "musl/src/math/__math_uflow.c",
......@@ -1137,6 +1147,7 @@ const src_files = [_][]const u8{
11371147 "musl/src/math/sinhl.c",
11381148 "musl/src/math/sinl.c",
11391149 "musl/src/math/sqrt.c",
1150 "musl/src/math/sqrt_data.c",
11401151 "musl/src/math/sqrtf.c",
11411152 "musl/src/math/sqrtl.c",
11421153 "musl/src/math/tan.c",
......@@ -1406,6 +1417,7 @@ const src_files = [_][]const u8{
14061417 "musl/src/prng/random.c",
14071418 "musl/src/prng/seed48.c",
14081419 "musl/src/prng/srand48.c",
1420 "musl/src/process/_Fork.c",
14091421 "musl/src/process/arm/vfork.s",
14101422 "musl/src/process/execl.c",
14111423 "musl/src/process/execle.c",
......@@ -1833,8 +1845,10 @@ const src_files = [_][]const u8{
18331845 "musl/src/termios/tcflush.c",
18341846 "musl/src/termios/tcgetattr.c",
18351847 "musl/src/termios/tcgetsid.c",
1848 "musl/src/termios/tcgetwinsize.c",
18361849 "musl/src/termios/tcsendbreak.c",
18371850 "musl/src/termios/tcsetattr.c",
1851 "musl/src/termios/tcsetwinsize.c",
18381852 "musl/src/thread/__lock.c",
18391853 "musl/src/thread/__set_thread_area.c",
18401854 "musl/src/thread/__syscall_cp.c",