aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/sys/auxv.h2
-rw-r--r--src/ldso/loongarch64/tlsdesc.s37
-rw-r--r--src/locale/bind_textdomain_codeset.c6
-rw-r--r--src/locale/iconv.c8
-rw-r--r--src/misc/mntent.c10
-rw-r--r--src/mq/x32/mq_open.c22
-rw-r--r--src/mq/x32/mq_setattr.c14
-rw-r--r--src/multibyte/mbsnrtowcs.c6
-rw-r--r--src/network/res_msend.c2
-rw-r--r--src/signal/riscv32/restore.s2
-rw-r--r--src/signal/riscv64/restore.s2
-rw-r--r--src/signal/sigpause.c2
-rw-r--r--src/stdio/__stdio_write.c5
-rw-r--r--src/stdio/vfprintf.c12
-rw-r--r--src/string/strcasestr.c1
-rw-r--r--src/termios/cfgetospeed.c2
-rw-r--r--src/termios/cfsetospeed.c10
-rw-r--r--src/termios/cfsetspeed.c11
-rw-r--r--src/thread/aarch64/__set_thread_area.c27
-rw-r--r--src/thread/aarch64/__set_thread_area.s7
-rw-r--r--src/thread/aarch64/clone.s3
-rw-r--r--src/thread/arm/clone.s3
-rw-r--r--src/thread/loongarch64/clone.s1
-rw-r--r--src/thread/m68k/clone.s3
-rw-r--r--src/thread/microblaze/clone.s3
-rw-r--r--src/thread/mips/clone.s3
-rw-r--r--src/thread/mips64/clone.s3
-rw-r--r--src/thread/mipsn32/clone.s3
-rw-r--r--src/thread/or1k/clone.s5
-rw-r--r--src/thread/riscv32/clone.s1
-rw-r--r--src/thread/riscv64/clone.s1
-rw-r--r--src/thread/s390x/__tls_get_offset.s20
-rw-r--r--src/time/timer_create.c11
33 files changed, 203 insertions, 45 deletions
diff --git a/src/include/sys/auxv.h b/src/include/sys/auxv.h
index 9358a4a..63c5bfe 100644
--- a/src/include/sys/auxv.h
+++ b/src/include/sys/auxv.h
@@ -5,6 +5,6 @@
#include <features.h>
-hidden unsigned long __getauxval(unsigned long);
+unsigned long __getauxval(unsigned long);
#endif
diff --git a/src/ldso/loongarch64/tlsdesc.s b/src/ldso/loongarch64/tlsdesc.s
new file mode 100644
index 0000000..4b6ea0e
--- /dev/null
+++ b/src/ldso/loongarch64/tlsdesc.s
@@ -0,0 +1,37 @@
+.text
+.global __tlsdesc_static
+.hidden __tlsdesc_static
+.type __tlsdesc_static,%function
+__tlsdesc_static:
+ ld.d $a0, $a0, 8
+ jr $ra
+# size_t __tlsdesc_dynamic(size_t *a)
+# {
+# struct {size_t modidx,off;} *p = (void*)a[1];
+# size_t *dtv = *(size_t**)(tp - 8);
+# return dtv[p->modidx] + p->off - tp;
+# }
+.global __tlsdesc_dynamic
+.hidden __tlsdesc_dynamic
+.type __tlsdesc_dynamic,%function
+__tlsdesc_dynamic:
+ addi.d $sp, $sp, -16
+ st.d $t1, $sp, 0
+ st.d $t2, $sp, 8
+
+ ld.d $t2, $tp, -8 # t2=dtv
+
+ ld.d $a0, $a0, 8 # a0=&{modidx,off}
+ ld.d $t1, $a0, 8 # t1=off
+ ld.d $a0, $a0, 0 # a0=modidx
+ slli.d $a0, $a0, 3 # a0=8*modidx
+
+ add.d $a0, $a0, $t2 # a0=dtv+8*modidx
+ ld.d $a0, $a0, 0 # a0=dtv[modidx]
+ add.d $a0, $a0, $t1 # a0=dtv[modidx]+off
+ sub.d $a0, $a0, $tp # a0=dtv[modidx]+off-tp
+
+ ld.d $t1, $sp, 0
+ ld.d $t2, $sp, 8
+ addi.d $sp, $sp, 16
+ jr $ra
diff --git a/src/locale/bind_textdomain_codeset.c b/src/locale/bind_textdomain_codeset.c
index 5ebfd5e..240e83e 100644
--- a/src/locale/bind_textdomain_codeset.c
+++ b/src/locale/bind_textdomain_codeset.c
@@ -5,7 +5,9 @@
char *bind_textdomain_codeset(const char *domainname, const char *codeset)
{
- if (codeset && strcasecmp(codeset, "UTF-8"))
+ if (codeset && strcasecmp(codeset, "UTF-8")) {
errno = EINVAL;
- return NULL;
+ return 0;
+ }
+ return "UTF-8";
}
diff --git a/src/locale/iconv.c b/src/locale/iconv.c
index 7fb2e1e..5217895 100644
--- a/src/locale/iconv.c
+++ b/src/locale/iconv.c
@@ -339,6 +339,8 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri
} else if (d-159 <= 252-159) {
c++;
d -= 159;
+ } else {
+ goto ilseq;
}
if (c>=84) goto ilseq;
c = jis0208[c][d];
@@ -500,7 +502,7 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri
if (c >= 93 || d >= 94) {
c += (0xa1-0x81);
d += 0xa1;
- if (c >= 93 || c>=0xc6-0x81 && d>0x52)
+ if (c > 0xc6-0x81 || c==0xc6-0x81 && d>0x52)
goto ilseq;
if (d-'A'<26) d = d-'A';
else if (d-'a'<26) d = d-'a'+26;
@@ -543,6 +545,10 @@ size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restri
if (*outb < k) goto toobig;
memcpy(*out, tmp, k);
} else k = wctomb_utf8(*out, c);
+ /* This failure condition should be unreachable, but
+ * is included to prevent decoder bugs from translating
+ * into advancement outside the output buffer range. */
+ if (k>4) goto ilseq;
*out += k;
*outb -= k;
break;
diff --git a/src/misc/mntent.c b/src/misc/mntent.c
index ee17a69..76f9c16 100644
--- a/src/misc/mntent.c
+++ b/src/misc/mntent.c
@@ -115,5 +115,13 @@ int addmntent(FILE *f, const struct mntent *mnt)
char *hasmntopt(const struct mntent *mnt, const char *opt)
{
- return strstr(mnt->mnt_opts, opt);
+ size_t l = strlen(opt);
+ char *p = mnt->mnt_opts;
+ for (;;) {
+ if (!strncmp(p, opt, l) && (!p[l] || p[l]==',' || p[l]=='='))
+ return p;
+ p = strchr(p, ',');
+ if (!p) return 0;
+ p++;
+ }
}
diff --git a/src/mq/x32/mq_open.c b/src/mq/x32/mq_open.c
new file mode 100644
index 0000000..2348195
--- /dev/null
+++ b/src/mq/x32/mq_open.c
@@ -0,0 +1,22 @@
+#include <mqueue.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include "syscall.h"
+
+mqd_t mq_open(const char *name, int flags, ...)
+{
+ mode_t mode = 0;
+ struct mq_attr *attr = 0;
+ long long attrbuf[8];
+ if (*name == '/') name++;
+ if (flags & O_CREAT) {
+ va_list ap;
+ va_start(ap, flags);
+ mode = va_arg(ap, mode_t);
+ attr = va_arg(ap, struct mq_attr *);
+ if (attr) for (int i=0; i<8; i++)
+ attrbuf[i] = *(long *)((char *)attr + i*sizeof(long));
+ va_end(ap);
+ }
+ return syscall(SYS_mq_open, name, flags, mode, attr?attrbuf:0);
+}
diff --git a/src/mq/x32/mq_setattr.c b/src/mq/x32/mq_setattr.c
new file mode 100644
index 0000000..0c63117
--- /dev/null
+++ b/src/mq/x32/mq_setattr.c
@@ -0,0 +1,14 @@
+#include <mqueue.h>
+#include "syscall.h"
+
+int mq_setattr(mqd_t mqd, const struct mq_attr *restrict new, struct mq_attr *restrict old)
+{
+ long long attr[8];
+ if (new) for (int i=0; i<8; i++)
+ attr[i] = *(long *)((char *)new + i*sizeof(long));
+ int ret = __syscall(SYS_mq_getsetattr, mqd, new?attr:0, old?attr:0);
+ if (ret < 0) return __syscall_ret(ret);
+ if (old) for (int i=0; i<8; i++)
+ *(long *)((char *)old + i*sizeof(long)) = attr[i];
+ return 0;
+}
diff --git a/src/multibyte/mbsnrtowcs.c b/src/multibyte/mbsnrtowcs.c
index 931192e..47cbdc0 100644
--- a/src/multibyte/mbsnrtowcs.c
+++ b/src/multibyte/mbsnrtowcs.c
@@ -2,11 +2,13 @@
size_t mbsnrtowcs(wchar_t *restrict wcs, const char **restrict src, size_t n, size_t wn, mbstate_t *restrict st)
{
+ static unsigned internal_state;
size_t l, cnt=0, n2;
wchar_t *ws, wbuf[256];
const char *s = *src;
const char *tmp_s;
+ if (!st) st = (void *)&internal_state;
if (!wcs) ws = wbuf, wn = sizeof wbuf / sizeof *wbuf;
else ws = wcs;
@@ -41,8 +43,8 @@ size_t mbsnrtowcs(wchar_t *restrict wcs, const char **restrict src, size_t n, si
s = 0;
break;
}
- /* have to roll back partial character */
- *(unsigned *)st = 0;
+ s += n;
+ n -= n;
break;
}
s += l; n -= l;
diff --git a/src/network/res_msend.c b/src/network/res_msend.c
index 86c2fcf..fcb5251 100644
--- a/src/network/res_msend.c
+++ b/src/network/res_msend.c
@@ -83,8 +83,8 @@ int __res_msend_rc(int nqueries, const unsigned char *const *queries,
int fd;
int timeout, attempts, retry_interval, servfail_retry;
union {
- struct sockaddr_in sin;
struct sockaddr_in6 sin6;
+ struct sockaddr_in sin;
} sa = {0}, ns[MAXNS] = {{0}};
socklen_t sl = sizeof sa.sin;
int nns = 0;
diff --git a/src/signal/riscv32/restore.s b/src/signal/riscv32/restore.s
index 40012c7..5a0af69 100644
--- a/src/signal/riscv32/restore.s
+++ b/src/signal/riscv32/restore.s
@@ -1,7 +1,9 @@
.global __restore
+.hidden __restore
.type __restore, %function
__restore:
.global __restore_rt
+.hidden __restore_rt
.type __restore_rt, %function
__restore_rt:
li a7, 139 # SYS_rt_sigreturn
diff --git a/src/signal/riscv64/restore.s b/src/signal/riscv64/restore.s
index 40012c7..5a0af69 100644
--- a/src/signal/riscv64/restore.s
+++ b/src/signal/riscv64/restore.s
@@ -1,7 +1,9 @@
.global __restore
+.hidden __restore
.type __restore, %function
__restore:
.global __restore_rt
+.hidden __restore_rt
.type __restore_rt, %function
__restore_rt:
li a7, 139 # SYS_rt_sigreturn
diff --git a/src/signal/sigpause.c b/src/signal/sigpause.c
index 363d2fe..1587c39 100644
--- a/src/signal/sigpause.c
+++ b/src/signal/sigpause.c
@@ -4,6 +4,6 @@ int sigpause(int sig)
{
sigset_t mask;
sigprocmask(0, 0, &mask);
- sigdelset(&mask, sig);
+ if (sigdelset(&mask, sig)) return -1;
return sigsuspend(&mask);
}
diff --git a/src/stdio/__stdio_write.c b/src/stdio/__stdio_write.c
index d2d8947..5356553 100644
--- a/src/stdio/__stdio_write.c
+++ b/src/stdio/__stdio_write.c
@@ -11,6 +11,11 @@ size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len)
size_t rem = iov[0].iov_len + iov[1].iov_len;
int iovcnt = 2;
ssize_t cnt;
+
+ if (!iov->iov_len) {
+ iov++;
+ iovcnt--;
+ }
for (;;) {
cnt = syscall(SYS_writev, f->fd, iov, iovcnt);
if (cnt == rem) {
diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c
index 7673399..a68edab 100644
--- a/src/stdio/vfprintf.c
+++ b/src/stdio/vfprintf.c
@@ -180,11 +180,11 @@ typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)
static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t, int ps)
{
- int bufsize = (ps==BIGLPRE)
- ? (LDBL_MANT_DIG+28)/29 + 1 + // mantissa expansion
- (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9 // exponent expansion
- : (DBL_MANT_DIG+28)/29 + 1 +
- (DBL_MAX_EXP+DBL_MANT_DIG+28+8)/9;
+ int max_mant_dig = (ps==BIGLPRE) ? LDBL_MANT_DIG : DBL_MANT_DIG;
+ int max_exp = (ps==BIGLPRE) ? LDBL_MAX_EXP : DBL_MAX_EXP;
+ int max_mant_slots = (max_mant_dig+28)/29 + 1;
+ int max_exp_slots = (max_exp+max_mant_dig+28+8)/9;
+ int bufsize = max_mant_slots + max_exp_slots;
uint32_t big[bufsize];
uint32_t *a, *d, *r, *z;
int e2=0, e, i, j, l;
@@ -266,7 +266,7 @@ static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t, int ps)
if (y) y *= 0x1p28, e2-=28;
if (e2<0) a=r=z=big;
- else a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1;
+ else a=r=z=big+sizeof(big)/sizeof(*big) - max_mant_slots - 1;
do {
*z = y;
diff --git a/src/string/strcasestr.c b/src/string/strcasestr.c
index af109f3..dc598bc 100644
--- a/src/string/strcasestr.c
+++ b/src/string/strcasestr.c
@@ -4,6 +4,7 @@
char *strcasestr(const char *h, const char *n)
{
size_t l = strlen(n);
+ if (!l) return (char *)h;
for (; *h; h++) if (!strncasecmp(h, n, l)) return (char *)h;
return 0;
}
diff --git a/src/termios/cfgetospeed.c b/src/termios/cfgetospeed.c
index 55fa6f5..de46a1d 100644
--- a/src/termios/cfgetospeed.c
+++ b/src/termios/cfgetospeed.c
@@ -9,5 +9,5 @@ speed_t cfgetospeed(const struct termios *tio)
speed_t cfgetispeed(const struct termios *tio)
{
- return cfgetospeed(tio);
+ return (tio->c_cflag & CIBAUD) / (CIBAUD/CBAUD);
}
diff --git a/src/termios/cfsetospeed.c b/src/termios/cfsetospeed.c
index c9cbdd9..3eab092 100644
--- a/src/termios/cfsetospeed.c
+++ b/src/termios/cfsetospeed.c
@@ -16,7 +16,11 @@ int cfsetospeed(struct termios *tio, speed_t speed)
int cfsetispeed(struct termios *tio, speed_t speed)
{
- return speed ? cfsetospeed(tio, speed) : 0;
+ if (speed & ~CBAUD) {
+ errno = EINVAL;
+ return -1;
+ }
+ tio->c_cflag &= ~CIBAUD;
+ tio->c_cflag |= speed * (CIBAUD/CBAUD);
+ return 0;
}
-
-weak_alias(cfsetospeed, cfsetspeed);
diff --git a/src/termios/cfsetspeed.c b/src/termios/cfsetspeed.c
new file mode 100644
index 0000000..2c369db
--- /dev/null
+++ b/src/termios/cfsetspeed.c
@@ -0,0 +1,11 @@
+#define _BSD_SOURCE
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+int cfsetspeed(struct termios *tio, speed_t speed)
+{
+ int r = cfsetospeed(tio, speed);
+ if (!r) cfsetispeed(tio, 0);
+ return r;
+}
diff --git a/src/thread/aarch64/__set_thread_area.c b/src/thread/aarch64/__set_thread_area.c
new file mode 100644
index 0000000..2ec788e
--- /dev/null
+++ b/src/thread/aarch64/__set_thread_area.c
@@ -0,0 +1,27 @@
+#include <elf.h>
+#include "libc.h"
+
+#define BITRANGE(a,b) (2*(1UL<<(b))-(1UL<<(a)))
+
+int __set_thread_area(void *p)
+{
+ __asm__ __volatile__ ("msr tpidr_el0,%0" : : "r"(p) : "memory");
+
+ /* Mask off hwcap bits for SME and unknown future features. This is
+ * necessary because SME is not safe to use without libc support for
+ * it, and we do not (yet) have such support. */
+ for (size_t *v = libc.auxv; *v; v+=2) {
+ if (v[0]==AT_HWCAP) {
+ v[1] &= ~BITRANGE(42,63); /* 42-47 are SME */
+ } else if (v[0]==AT_HWCAP2) {
+ v[1] &= ~(BITRANGE(23,30)
+ | BITRANGE(37,42)
+ | BITRANGE(57,62));
+ } else if (v[0]==AT_HWCAP3 || v[0]==AT_HWCAP4) {
+ v[0] = AT_IGNORE;
+ v[1] = 0;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/thread/aarch64/__set_thread_area.s b/src/thread/aarch64/__set_thread_area.s
deleted file mode 100644
index fd0df34..0000000
--- a/src/thread/aarch64/__set_thread_area.s
+++ /dev/null
@@ -1,7 +0,0 @@
-.global __set_thread_area
-.hidden __set_thread_area
-.type __set_thread_area,@function
-__set_thread_area:
- msr tpidr_el0,x0
- mov w0,#0
- ret
diff --git a/src/thread/aarch64/clone.s b/src/thread/aarch64/clone.s
index e3c8339..aff8155 100644
--- a/src/thread/aarch64/clone.s
+++ b/src/thread/aarch64/clone.s
@@ -24,7 +24,8 @@ __clone:
// parent
ret
// child
-1: ldp x1,x0,[sp],#16
+1: mov x29, 0
+ ldp x1,x0,[sp],#16
blr x1
mov x8,#93 // SYS_exit
svc #0
diff --git a/src/thread/arm/clone.s b/src/thread/arm/clone.s
index bb0965d..4ff0c0e 100644
--- a/src/thread/arm/clone.s
+++ b/src/thread/arm/clone.s
@@ -19,7 +19,8 @@ __clone:
ldmfd sp!,{r4,r5,r6,r7}
bx lr
-1: mov r0,r6
+1: mov fp,#0
+ mov r0,r6
bl 3f
2: mov r7,#1
svc 0
diff --git a/src/thread/loongarch64/clone.s b/src/thread/loongarch64/clone.s
index a165b36..cb4aacf 100644
--- a/src/thread/loongarch64/clone.s
+++ b/src/thread/loongarch64/clone.s
@@ -22,6 +22,7 @@ __clone:
beqz $a0, 1f # whether child process
jirl $zero, $ra, 0 # parent process return
1:
+ move $fp, $zero
ld.d $t8, $sp, 0 # function pointer
ld.d $a0, $sp, 8 # argument pointer
jirl $ra, $t8, 0 # call the user's function
diff --git a/src/thread/m68k/clone.s b/src/thread/m68k/clone.s
index f6dfa06..0134cf4 100644
--- a/src/thread/m68k/clone.s
+++ b/src/thread/m68k/clone.s
@@ -18,7 +18,8 @@ __clone:
beq 1f
movem.l (%sp)+,%d2-%d5
rts
-1: move.l %a1,-(%sp)
+1: suba.l %fp,%fp
+ move.l %a1,-(%sp)
jsr (%a0)
move.l #1,%d0
trap #0
diff --git a/src/thread/microblaze/clone.s b/src/thread/microblaze/clone.s
index b68cc5f..64e3f07 100644
--- a/src/thread/microblaze/clone.s
+++ b/src/thread/microblaze/clone.s
@@ -22,7 +22,8 @@ __clone:
rtsd r15, 8
nop
-1: lwi r3, r1, 0
+1: add r19, r0, r0
+ lwi r3, r1, 0
lwi r5, r1, 4
brald r15, r3
nop
diff --git a/src/thread/mips/clone.s b/src/thread/mips/clone.s
index 0446338..229b987 100644
--- a/src/thread/mips/clone.s
+++ b/src/thread/mips/clone.s
@@ -27,7 +27,8 @@ __clone:
addu $sp, $sp, 16
jr $ra
nop
-1: lw $25, 0($sp)
+1: move $fp, $0
+ lw $25, 0($sp)
lw $4, 4($sp)
jalr $25
nop
diff --git a/src/thread/mips64/clone.s b/src/thread/mips64/clone.s
index 2d86899..8de3db6 100644
--- a/src/thread/mips64/clone.s
+++ b/src/thread/mips64/clone.s
@@ -25,7 +25,8 @@ __clone:
nop
jr $ra
nop
-1: ld $25, 0($sp) # function pointer
+1: move $fp, $0
+ ld $25, 0($sp) # function pointer
ld $4, 8($sp) # argument pointer
jalr $25 # call the user's function
nop
diff --git a/src/thread/mipsn32/clone.s b/src/thread/mipsn32/clone.s
index 4d3c8c7..9571231 100644
--- a/src/thread/mipsn32/clone.s
+++ b/src/thread/mipsn32/clone.s
@@ -25,7 +25,8 @@ __clone:
nop
jr $ra
nop
-1: lw $25, 0($sp) # function pointer
+1: move $fp, $0
+ lw $25, 0($sp) # function pointer
lw $4, 4($sp) # argument pointer
jalr $25 # call the user's function
nop
diff --git a/src/thread/or1k/clone.s b/src/thread/or1k/clone.s
index 2473ac2..b41488a 100644
--- a/src/thread/or1k/clone.s
+++ b/src/thread/or1k/clone.s
@@ -6,6 +6,8 @@
.hidden __clone
.type __clone,@function
__clone:
+ l.xori r11, r0, -4
+ l.and r4, r4, r11
l.addi r4, r4, -8
l.sw 0(r4), r3
l.sw 4(r4), r6
@@ -23,7 +25,8 @@ __clone:
l.jr r9
l.nop
-1: l.lwz r11, 0(r1)
+1: l.ori r2, r0, 0
+ l.lwz r11, 0(r1)
l.jalr r11
l.lwz r3, 4(r1)
diff --git a/src/thread/riscv32/clone.s b/src/thread/riscv32/clone.s
index 3102239..e2116e3 100644
--- a/src/thread/riscv32/clone.s
+++ b/src/thread/riscv32/clone.s
@@ -8,6 +8,7 @@
.type __clone, %function
__clone:
# Save func and arg to stack
+ andi a1, a1, -16
addi a1, a1, -16
sw a0, 0(a1)
sw a3, 4(a1)
diff --git a/src/thread/riscv64/clone.s b/src/thread/riscv64/clone.s
index db90824..0e6f41a 100644
--- a/src/thread/riscv64/clone.s
+++ b/src/thread/riscv64/clone.s
@@ -8,6 +8,7 @@
.type __clone, %function
__clone:
# Save func and arg to stack
+ andi a1, a1, -16
addi a1, a1, -16
sd a0, 0(a1)
sd a3, 8(a1)
diff --git a/src/thread/s390x/__tls_get_offset.s b/src/thread/s390x/__tls_get_offset.s
index 8ee92de..405f118 100644
--- a/src/thread/s390x/__tls_get_offset.s
+++ b/src/thread/s390x/__tls_get_offset.s
@@ -1,17 +1,17 @@
.global __tls_get_offset
.type __tls_get_offset,%function
__tls_get_offset:
- stmg %r14, %r15, 112(%r15)
- aghi %r15, -160
+ ear %r0, %a0
+ sllg %r0, %r0, 32
+ ear %r0, %a1
- la %r2, 0(%r2, %r12)
- brasl %r14, __tls_get_addr
+ la %r1, 0(%r2, %r12)
- ear %r1, %a0
- sllg %r1, %r1, 32
- ear %r1, %a1
+ lg %r3, 0(%r1)
+ sllg %r4, %r3, 3
+ lg %r5, 8(%r0)
+ lg %r2, 0(%r4, %r5)
+ ag %r2, 8(%r1)
+ sgr %r2, %r0
- sgr %r2, %r1
-
- lmg %r14, %r15, 272(%r15)
br %r14
diff --git a/src/time/timer_create.c b/src/time/timer_create.c
index 424c70b..cc6c223 100644
--- a/src/time/timer_create.c
+++ b/src/time/timer_create.c
@@ -22,10 +22,16 @@ static void dummy_0()
}
weak_alias(dummy_0, __pthread_tsd_run_dtors);
+static void timer_handler(int sig, siginfo_t *si, void *ctx)
+{
+}
+
static void cleanup_fromsig(void *p)
{
pthread_t self = __pthread_self();
__pthread_tsd_run_dtors();
+ __block_app_sigs(0);
+ __syscall(SYS_rt_sigprocmask, SIG_BLOCK, SIGTIMER_SET, 0, _NSIG/8);
self->cancel = 0;
self->cancelbuf = 0;
self->canceldisable = 0;
@@ -98,7 +104,10 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict
break;
case SIGEV_THREAD:
if (!init) {
- struct sigaction sa = { .sa_handler = SIG_DFL };
+ struct sigaction sa = {
+ .sa_sigaction = timer_handler,
+ .sa_flags = SA_SIGINFO | SA_RESTART
+ };
__libc_sigaction(SIGTIMER, &sa, 0);
a_store(&init, 1);
}