summaryrefslogtreecommitdiff
path: root/klibc/klibc
diff options
context:
space:
mode:
Diffstat (limited to 'klibc/klibc')
-rw-r--r--klibc/klibc/SYSCALLS.def32
-rw-r--r--klibc/klibc/arch/i386/Makefile.inc1
-rw-r--r--klibc/klibc/arch/x86_64/MCONFIG5
-rw-r--r--klibc/klibc/arch/x86_64/Makefile.inc3
-rw-r--r--klibc/klibc/arch/x86_64/syscall.S6
-rw-r--r--klibc/klibc/fgets.c1
-rw-r--r--klibc/klibc/sigaction.c35
-rw-r--r--klibc/klibc/sigpending.c4
-rw-r--r--klibc/klibc/sigprocmask.c4
-rw-r--r--klibc/klibc/sigsuspend.c4
-rw-r--r--klibc/klibc/strntoumax.c13
11 files changed, 82 insertions, 26 deletions
diff --git a/klibc/klibc/SYSCALLS.def b/klibc/klibc/SYSCALLS.def
index e8b9a7f176..11d8c9a47e 100644
--- a/klibc/klibc/SYSCALLS.def
+++ b/klibc/klibc/SYSCALLS.def
@@ -145,17 +145,29 @@ ssize_t pwrite64,pwrite::pwrite(int, void *, size_t, off_t)
;
; Signal operations
;
-int kill(pid_t, int)
; We really should get rid of the non-rt_* of these, but that takes
-; sanitizing <signal.h> for all architectures, sigh...
-<?> int sigaction(int, const struct sigaction *, struct sigaction *)
-<?> int sigsuspend(const sigset_t *)
-<?> int sigpending(sigset_t *)
-<?> int sigprocmask(int, const sigset_t *, sigset_t *)
-int rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t)
-int rt_sigsuspend(const sigset_t *, size_t)
-int rt_sigpending(sigset_t *, size_t)
-int rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t)
+; sanitizing <signal.h> for all architectures, sigh.
+#ifdef __NR_sigaction
+int sigaction::__sigaction(int, const struct sigaction *, struct sigaction *)
+#else
+int rt_sigaction::__rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t)
+#endif
+#ifdef __NR_sigsuspend
+int sigsuspend(const sigset_t *)
+#else
+int rt_sigsuspend::__rt_sigsuspend(const sigset_t *, size_t)
+#endif
+#ifdef __NR_sigpending
+int sigpending(sigset_t *)
+#else
+int rt_sigpending::__rt_sigpending(sigset_t *, size_t)
+#endif
+#ifdef __NR_sigprocmask
+int sigprocmask(int, const sigset_t *, sigset_t *)
+#else
+int rt_sigprocmask::__rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t)
+#endif
+int kill(pid_t, int)
<?> unsigned int alarm(unsigned int)
int getitimer(int, struct itimerval *)
int setitimer(int, const struct itimerval *, struct itimerval *)
diff --git a/klibc/klibc/arch/i386/Makefile.inc b/klibc/klibc/arch/i386/Makefile.inc
index 5c320cb453..80344bd0a5 100644
--- a/klibc/klibc/arch/i386/Makefile.inc
+++ b/klibc/klibc/arch/i386/Makefile.inc
@@ -13,6 +13,7 @@ ARCHOBJS = \
arch/$(ARCH)/setjmp.o \
arch/$(ARCH)/syscall.o \
arch/$(ARCH)/open.o \
+ arch/$(ARCH)/sigreturn.o \
arch/$(ARCH)/libgcc/__ashldi3.o \
arch/$(ARCH)/libgcc/__ashrdi3.o \
arch/$(ARCH)/libgcc/__lshrdi3.o \
diff --git a/klibc/klibc/arch/x86_64/MCONFIG b/klibc/klibc/arch/x86_64/MCONFIG
index 13b6e391f9..c9b5da8bd6 100644
--- a/klibc/klibc/arch/x86_64/MCONFIG
+++ b/klibc/klibc/arch/x86_64/MCONFIG
@@ -15,8 +15,13 @@
# debugging using gdb.
#
ARCHREQFLAGS = -m64
+ifeq ($(DEBUG),y)
+OPTFLAGS = -Os -fomit-frame-pointer \
+ -falign-functions=0 -falign-jumps=0 -falign-loops=0
+else
OPTFLAGS = -Os -fno-asynchronous-unwind-tables -fomit-frame-pointer \
-falign-functions=0 -falign-jumps=0 -falign-loops=0
+endif
BITSIZE = 64
LDFLAGS = -m elf_x86_64
diff --git a/klibc/klibc/arch/x86_64/Makefile.inc b/klibc/klibc/arch/x86_64/Makefile.inc
index d6cc1204e4..26d880d7c7 100644
--- a/klibc/klibc/arch/x86_64/Makefile.inc
+++ b/klibc/klibc/arch/x86_64/Makefile.inc
@@ -10,7 +10,8 @@
ARCHOBJS = \
arch/$(ARCH)/exits.o \
arch/$(ARCH)/setjmp.o \
- arch/$(ARCH)/syscall.o
+ arch/$(ARCH)/syscall.o \
+ arch/$(ARCH)/sigreturn.o
ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS))
diff --git a/klibc/klibc/arch/x86_64/syscall.S b/klibc/klibc/arch/x86_64/syscall.S
index f2c74ae974..17977978b9 100644
--- a/klibc/klibc/arch/x86_64/syscall.S
+++ b/klibc/klibc/arch/x86_64/syscall.S
@@ -15,14 +15,14 @@ __syscall_common:
syscall
cmpq $-4095,%rax
- jb 1f
+ jnb 1f
+ ret
# Error return, must set errno
+1:
negl %eax
movl %eax,errno(%rip) # errno is type int, so 32 bits
orq $-1,%rax # orq $-1 smaller than movq $-1
-
-1:
ret
.size __syscall_common,.-__syscall_common
diff --git a/klibc/klibc/fgets.c b/klibc/klibc/fgets.c
index 88a145a63f..72f8a13cf1 100644
--- a/klibc/klibc/fgets.c
+++ b/klibc/klibc/fgets.c
@@ -20,6 +20,7 @@ char *fgets(char *s, int n, FILE *f)
return NULL;
}
*p++ = ch;
+ n--;
if ( ch == '\n' )
break;
}
diff --git a/klibc/klibc/sigaction.c b/klibc/klibc/sigaction.c
index 819ffd4fe8..85f42a244c 100644
--- a/klibc/klibc/sigaction.c
+++ b/klibc/klibc/sigaction.c
@@ -5,11 +5,40 @@
#include <signal.h>
#include <sys/syscall.h>
-#ifndef __NR_sigaction
+__extern void __sigreturn(void);
+__extern int __sigaction(int, const struct sigaction *, struct sigaction *);
+__extern int __rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t);
int sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
{
- return rt_sigaction(sig, act, oact, sizeof(sigset_t));
-}
+ int rv;
+
+#if defined(__i386__) || defined(__x86_64__)
+ /* x86-64, and the Fedora i386 kernel, are broken without SA_RESTORER */
+ struct sigaction sa;
+
+ if ( act && !(act->sa_flags & SA_RESTORER) ) {
+ sa = *act;
+ act = &sa;
+
+ /* The kernel can't be trusted to have a valid default restorer */
+ sa.sa_flags |= SA_RESTORER;
+ sa.sa_restorer = &__sigreturn;
+ }
+#endif
+#ifdef __NR_sigaction
+ rv = __sigaction(sig, act, oact);
+#else
+ rv = __rt_sigaction(sig, act, oact, sizeof(sigset_t));
#endif
+
+
+#if defined(__i386__) || defined(__x86_64__)
+ if ( oact && (oact->sa_restorer == &__sigreturn) ) {
+ oact->sa_flags &= ~SA_RESTORER;
+ }
+#endif
+
+ return rv;
+}
diff --git a/klibc/klibc/sigpending.c b/klibc/klibc/sigpending.c
index 76d2b1a7f6..decfe32b1b 100644
--- a/klibc/klibc/sigpending.c
+++ b/klibc/klibc/sigpending.c
@@ -7,9 +7,11 @@
#ifndef __NR_sigpending
+__extern __rt_sigpending(sigset_t *, size_t);
+
int sigpending(sigset_t *set)
{
- return rt_sigpending(set, sizeof(sigset_t));
+ return __rt_sigpending(set, sizeof(sigset_t));
}
#endif
diff --git a/klibc/klibc/sigprocmask.c b/klibc/klibc/sigprocmask.c
index b5e58b28b8..372e0fd90d 100644
--- a/klibc/klibc/sigprocmask.c
+++ b/klibc/klibc/sigprocmask.c
@@ -7,9 +7,11 @@
#ifndef __NR_sigprocmask
+__extern __rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t);
+
int sigprocmask(int how, const sigset_t *set, sigset_t *oset)
{
- return rt_sigprocmask(how, set, oset, sizeof(sigset_t));
+ return __rt_sigprocmask(how, set, oset, sizeof(sigset_t));
}
#endif
diff --git a/klibc/klibc/sigsuspend.c b/klibc/klibc/sigsuspend.c
index a927999ae6..22f9a46681 100644
--- a/klibc/klibc/sigsuspend.c
+++ b/klibc/klibc/sigsuspend.c
@@ -7,9 +7,11 @@
#ifndef __NR_sigsuspend
+__extern int __rt_sigsuspend(const sigset_t *, size_t);
+
int sigsuspend(const sigset_t *mask)
{
- return rt_sigsuspend(mask, sizeof *mask);
+ return __rt_sigsuspend(mask, sizeof *mask);
}
#endif
diff --git a/klibc/klibc/strntoumax.c b/klibc/klibc/strntoumax.c
index 4e30637d2c..4c47fe8662 100644
--- a/klibc/klibc/strntoumax.c
+++ b/klibc/klibc/strntoumax.c
@@ -33,12 +33,13 @@ uintmax_t strntoumax(const char *nptr, char **endptr, int base, size_t n)
}
/* Single optional + or - */
- if ( n && *nptr == '-' ) {
- minus = 1;
- nptr++;
- n--;
- } else if ( n && *nptr == '+' ) {
- nptr++;
+ if ( n ) {
+ char c = *nptr;
+ if ( c == '-' || c == '+' ) {
+ minus = (c == '-');
+ nptr++;
+ n--;
+ }
}
if ( base == 0 ) {