The user-space signature of the sigsuspend() function differs a lot from the Linux syscall sigsuspend one. Unfortunately, it differs across the architectures, as well. Also, while the RT signal functions are available on all Linux architectures, they cannot be used on all architectures by klibc because the kernel headers do not expose everything as needed by them. This patch switches the mips architectures to RT signals and fixes sigsuspend() on all other klibc architectures by renaming the syscall to __n_sigsuspend() and writing an appropriate wrapper function. Signed-off-by: Thorsten Glaser <tg at mirbsd.org> --- usr/include/arch/alpha/klibc/archconfig.h | 1 + usr/include/arch/arm/klibc/archconfig.h | 2 ++ usr/include/arch/cris/klibc/archconfig.h | 2 ++ usr/include/arch/i386/klibc/archconfig.h | 1 + usr/include/arch/m68k/klibc/archconfig.h | 2 ++ usr/include/arch/mips/klibc/archconfig.h | 3 +++ usr/include/arch/mips64/klibc/archconfig.h | 3 +++ usr/include/arch/ppc/klibc/archconfig.h | 2 +- usr/include/arch/s390/klibc/archconfig.h | 2 ++ usr/include/arch/sh/klibc/archconfig.h | 2 +- usr/include/arch/sparc/klibc/archconfig.h | 1 + usr/include/arch/sparc64/klibc/archconfig.h | 1 + usr/include/klibc/sysconfig.h | 32 +++++++++++++++++++++++++++ usr/klibc/SYSCALLS.def | 13 ++++++++++- usr/klibc/sigsuspend.c | 27 ++++++++++++++++++++++ 15 files changed, 91 insertions(+), 3 deletions(-) diff --git a/usr/include/arch/alpha/klibc/archconfig.h b/usr/include/arch/alpha/klibc/archconfig.h index 272fee0..be6ef39 100644 --- a/usr/include/arch/alpha/klibc/archconfig.h +++ b/usr/include/arch/alpha/klibc/archconfig.h @@ -11,5 +11,6 @@ #define _KLIBC_USE_RT_SIG 1 #define _KLIBC_STATFS_F_TYPE_64 0 +#define _KLIBC_SIGSUSPEND_TYPE _KLIBC_SIGSUSPEND_TYPE_L_1 #endif /* _KLIBC_ARCHCONFIG_H */ diff --git a/usr/include/arch/arm/klibc/archconfig.h b/usr/include/arch/arm/klibc/archconfig.h index 36e9ab5..a0b5e96 100644 --- a/usr/include/arch/arm/klibc/archconfig.h +++ b/usr/include/arch/arm/klibc/archconfig.h @@ -15,4 +15,6 @@ # define _KLIBC_ARM_USE_BX 1 #endif +#define _KLIBC_SIGSUSPEND_TYPE _KLIBC_SIGSUSPEND_TYPE_I_IUL1 + #endif /* _KLIBC_ARCHCONFIG_H */ diff --git a/usr/include/arch/cris/klibc/archconfig.h b/usr/include/arch/cris/klibc/archconfig.h index 0206078..f61a074 100644 --- a/usr/include/arch/cris/klibc/archconfig.h +++ b/usr/include/arch/cris/klibc/archconfig.h @@ -12,4 +12,6 @@ /* cris uses 13 as the page shift factor for sys_mmap2 */ #define _KLIBC_MMAP2_SHIFT 13 +#define _KLIBC_SIGSUSPEND_TYPE _KLIBC_SIGSUSPEND_TYPE_I_1 + #endif /* _KLIBC_ARCHCONFIG_H */ diff --git a/usr/include/arch/i386/klibc/archconfig.h b/usr/include/arch/i386/klibc/archconfig.h index b409a21..6e926e1 100644 --- a/usr/include/arch/i386/klibc/archconfig.h +++ b/usr/include/arch/i386/klibc/archconfig.h @@ -11,5 +11,6 @@ /* The i386 <asm/signal.h> is still not clean enough for this... */ #define _KLIBC_USE_RT_SIG 0 +#define _KLIBC_SIGSUSPEND_TYPE _KLIBC_SIGSUSPEND_TYPE_I_II1 #endif /* _KLIBC_ARCHCONFIG_H */ diff --git a/usr/include/arch/m68k/klibc/archconfig.h b/usr/include/arch/m68k/klibc/archconfig.h index 10ef62e..ebb3420 100644 --- a/usr/include/arch/m68k/klibc/archconfig.h +++ b/usr/include/arch/m68k/klibc/archconfig.h @@ -12,4 +12,6 @@ /* On m68k, sys_mmap2 uses the current page size as the shift factor */ #define _KLIBC_MMAP2_SHIFT __getpageshift() +#define _KLIBC_SIGSUSPEND_TYPE _KLIBC_SIGSUSPEND_TYPE_I_II1 + #endif /* _KLIBC_ARCHCONFIG_H */ diff --git a/usr/include/arch/mips/klibc/archconfig.h b/usr/include/arch/mips/klibc/archconfig.h index ff0afb5..194fee1 100644 --- a/usr/include/arch/mips/klibc/archconfig.h +++ b/usr/include/arch/mips/klibc/archconfig.h @@ -18,4 +18,7 @@ /* MIPS has nonstandard socket definitions */ #define _KLIBC_HAS_ARCHSOCKET_H 1 +/* signal.h seems clean enough for RT signals; non-RT are broken */ +#define _KLIBC_USE_RT_SIG 1 + #endif /* _KLIBC_ARCHCONFIG_H */ diff --git a/usr/include/arch/mips64/klibc/archconfig.h b/usr/include/arch/mips64/klibc/archconfig.h index 9071cb4..a26addc 100644 --- a/usr/include/arch/mips64/klibc/archconfig.h +++ b/usr/include/arch/mips64/klibc/archconfig.h @@ -12,4 +12,7 @@ /* MIPS has nonstandard socket definitions */ #define _KLIBC_HAS_ARCHSOCKET_H 1 +/* signal.h seems clean enough for RT signals; non-RT are broken */ +#define _KLIBC_USE_RT_SIG 1 + #endif /* _KLIBC_ARCHCONFIG_H */ diff --git a/usr/include/arch/ppc/klibc/archconfig.h b/usr/include/arch/ppc/klibc/archconfig.h index ce04eee..aa32bcd 100644 --- a/usr/include/arch/ppc/klibc/archconfig.h +++ b/usr/include/arch/ppc/klibc/archconfig.h @@ -9,6 +9,6 @@ #ifndef _KLIBC_ARCHCONFIG_H #define _KLIBC_ARCHCONFIG_H -/* All defaults */ +#define _KLIBC_SIGSUSPEND_TYPE _KLIBC_SIGSUSPEND_TYPE_L_1 #endif /* _KLIBC_ARCHCONFIG_H */ diff --git a/usr/include/arch/s390/klibc/archconfig.h b/usr/include/arch/s390/klibc/archconfig.h index d7a71a4..d2a9fb3 100644 --- a/usr/include/arch/s390/klibc/archconfig.h +++ b/usr/include/arch/s390/klibc/archconfig.h @@ -12,4 +12,6 @@ /* Both s390 and s390x use the "32-bit" version of this structure */ #define _KLIBC_STATFS_F_TYPE_64 0 +#define _KLIBC_SIGSUSPEND_TYPE _KLIBC_SIGSUSPEND_TYPE_L_II1 + #endif /* _KLIBC_ARCHCONFIG_H */ diff --git a/usr/include/arch/sh/klibc/archconfig.h b/usr/include/arch/sh/klibc/archconfig.h index 9c9e3d8..83752f5 100644 --- a/usr/include/arch/sh/klibc/archconfig.h +++ b/usr/include/arch/sh/klibc/archconfig.h @@ -9,6 +9,6 @@ #ifndef _KLIBC_ARCHCONFIG_H #define _KLIBC_ARCHCONFIG_H -/* All defaults */ +#define _KLIBC_SIGSUSPEND_TYPE _KLIBC_SIGSUSPEND_TYPE_I_1 #endif /* _KLIBC_ARCHCONFIG_H */ diff --git a/usr/include/arch/sparc/klibc/archconfig.h b/usr/include/arch/sparc/klibc/archconfig.h index 70d5ef0..ab52362 100644 --- a/usr/include/arch/sparc/klibc/archconfig.h +++ b/usr/include/arch/sparc/klibc/archconfig.h @@ -11,5 +11,6 @@ #define _KLIBC_USE_RT_SIG 1 /* Use rt_* signals */ #define _KLIBC_SYS_SOCKETCALL 1 /* Use sys_socketcall unconditionally */ +#define _KLIBC_SIGSUSPEND_TYPE _KLIBC_SIGSUSPEND_TYPE_I_1 #endif /* _KLIBC_ARCHCONFIG_H */ diff --git a/usr/include/arch/sparc64/klibc/archconfig.h b/usr/include/arch/sparc64/klibc/archconfig.h index 794d15b..b2eb203 100644 --- a/usr/include/arch/sparc64/klibc/archconfig.h +++ b/usr/include/arch/sparc64/klibc/archconfig.h @@ -12,5 +12,6 @@ #define _KLIBC_USE_RT_SIG 1 /* Use rt_* signals */ #define _KLIBC_NEEDS_SA_RESTORER 1 /* Need a restorer function */ #define _KLIBC_SYS_SOCKETCALL 1 /* Use sys_socketcall unconditionally */ +#define _KLIBC_SIGSUSPEND_TYPE _KLIBC_SIGSUSPEND_TYPE_I_1 #endif /* _KLIBC_ARCHCONFIG_H */ diff --git a/usr/include/klibc/sysconfig.h b/usr/include/klibc/sysconfig.h index 5fa9b60..523e484 100644 --- a/usr/include/klibc/sysconfig.h +++ b/usr/include/klibc/sysconfig.h @@ -8,6 +8,24 @@ #ifndef _KLIBC_SYSCONFIG_H #define _KLIBC_SYSCONFIG_H +/* + * _KLIBC_SIGSUSPEND_TYPE_*: + * + * Enumerates the various types of sigsuspend() syscall + * we can use, for the architecture header to select one. + */ + +/* int sigsuspend(sigset_t) */ +#define _KLIBC_SIGSUSPEND_TYPE_I_1 1 +/* long sigsuspend(sigset_t) */ +#define _KLIBC_SIGSUSPEND_TYPE_L_1 2 +/* int sigsuspend(int, int, sigset_t) */ +#define _KLIBC_SIGSUSPEND_TYPE_I_II1 3 +/* long sigsuspend(int, int, sigset_t) */ +#define _KLIBC_SIGSUSPEND_TYPE_L_II1 4 +/* int sigsuspend(int, unsigned long, sigset_t) */ +#define _KLIBC_SIGSUSPEND_TYPE_I_IUL1 5 + #include <klibc/archconfig.h> #include <asm/unistd.h> @@ -216,4 +234,18 @@ # define _KLIBC_ARM_USE_BX 0 #endif +/* + * _KLIBC_SIGSUSPEND_TYPE + * + * Select which sigsuspend() type we have. + * Default to RT if _KLIBC_USE_RT_SIG, otherwise error out, + * as we cannot safely predict a non-RT type without the + * architecture-specific includes telling us which one it is. + */ +#ifndef _KLIBC_SIGSUSPEND_TYPE +# if !_KLIBC_USE_RT_SIG +# error Cannot use non-RT sigsuspend without knowing the type! +# endif +#endif + #endif /* _KLIBC_SYSCONFIG_H */ diff --git a/usr/klibc/SYSCALLS.def b/usr/klibc/SYSCALLS.def index 6ed6bdf..7abab15 100644 --- a/usr/klibc/SYSCALLS.def +++ b/usr/klibc/SYSCALLS.def @@ -206,9 +206,20 @@ int rt_sigprocmask::__rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t); <sparc64> void rt_sigreturn::__sigreturn(); #else int sigaction::__sigaction(int, const struct sigaction *, struct sigaction *); -int sigsuspend(const sigset_t *); int sigpending(sigset_t *); int sigprocmask(int, const sigset_t *, sigset_t *); +/* + * There is no single calling convention for the old sigsuspend. + * If your architecture is not listed here, building klibc shall + * rather fail than use a broken calling convention. + * You better switch to RT signals on those architectures: + * blackfin h8300 microblaze mips + */ +<cris,sh,sparc> int sigsuspend::__n_sigsuspend(sigset_t); +<alpha,powerpc,sparc64> long sigsuspend::__n_sigsuspend(sigset_t); +<arm> int sigsuspend::__n_sigsuspend(int, unsigned long, sigset_t); +<frv,i386,m68k> int sigsuspend::__n_sigsuspend(int, int, sigset_t); +<mn10300,s390> long sigsuspend::__n_sigsuspend(int, int, sigset_t); #endif int kill(pid_t, int); <?> unsigned int alarm(unsigned int); diff --git a/usr/klibc/sigsuspend.c b/usr/klibc/sigsuspend.c index 4d910d5..1b829c5 100644 --- a/usr/klibc/sigsuspend.c +++ b/usr/klibc/sigsuspend.c @@ -15,4 +15,31 @@ int sigsuspend(const sigset_t * mask) return __rt_sigsuspend(mask, sizeof *mask); } +#else + +#if _KLIBC_SIGSUSPEND_TYPE == _KLIBC_SIGSUSPEND_TYPE_I_1 +extern int __n_sigsuspend(sigset_t); +#elif _KLIBC_SIGSUSPEND_TYPE == _KLIBC_SIGSUSPEND_TYPE_L_1 +extern long __n_sigsuspend(sigset_t); +#elif _KLIBC_SIGSUSPEND_TYPE == _KLIBC_SIGSUSPEND_TYPE_I_II1 +extern int __n_sigsuspend(int, int, sigset_t); +#elif _KLIBC_SIGSUSPEND_TYPE == _KLIBC_SIGSUSPEND_TYPE_L_II1 +extern long __n_sigsuspend(int, int, sigset_t); +#elif _KLIBC_SIGSUSPEND_TYPE == _KLIBC_SIGSUSPEND_TYPE_I_IUL1 +extern int __n_sigsuspend(int, unsigned long, sigset_t); +#else +#error unknown architecture +#endif + +int +sigsuspend(const sigset_t *maskp) +{ +#if (_KLIBC_SIGSUSPEND_TYPE == _KLIBC_SIGSUSPEND_TYPE_I_1) || \ + (_KLIBC_SIGSUSPEND_TYPE == _KLIBC_SIGSUSPEND_TYPE_L_1) + return ((int)__n_sigsuspend(*maskp)); +#else + return ((int)__n_sigsuspend(0, 0, *maskp)); +#endif +} + #endif -- 1.7.10
Thorsten Glaser
2012-May-15 16:30 UTC
[klibc] [PATCH 4/5] Use GCC definitions for size_t, ssize_t, ptrdiff_t
Fall back to (unsigned) long if klibc userspace applications are compiled with something that is not GCC or close enough to also define its __SIZE_TYPE__ and __PTRDIFF_TYPE__ macros. Change the definition of ssize_t to be decoupled from ptrdiff_t and be derived from __SIZE_TYPE__ instead, dropping the unsigned. Signed-off-by: Thorsten Glaser <tg at mirbsd.org> --- usr/include/bits32/bitsize/stddef.h | 18 ------------------ usr/include/bits64/bitsize/stddef.h | 13 ------------- usr/include/stddef.h | 24 +++++++++++++++++++++++- usr/include/sys/types.h | 20 ++++---------------- 4 files changed, 27 insertions(+), 48 deletions(-) delete mode 100644 usr/include/bits32/bitsize/stddef.h delete mode 100644 usr/include/bits64/bitsize/stddef.h diff --git a/usr/include/bits32/bitsize/stddef.h b/usr/include/bits32/bitsize/stddef.h deleted file mode 100644 index 43d733c..0000000 --- a/usr/include/bits32/bitsize/stddef.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * bits32/stddef.h - */ - -#ifndef _BITSIZE_STDDEF_H -#define _BITSIZE_STDDEF_H - -#define _SIZE_T -#if defined(__s390__) || defined(__cris__) -typedef unsigned long size_t; -#else -typedef unsigned int size_t; -#endif - -#define _PTRDIFF_T -typedef signed int ptrdiff_t; - -#endif /* _BITSIZE_STDDEF_H */ diff --git a/usr/include/bits64/bitsize/stddef.h b/usr/include/bits64/bitsize/stddef.h deleted file mode 100644 index 1e942a1..0000000 --- a/usr/include/bits64/bitsize/stddef.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * bits64/stddef.h - */ - -#ifndef _BITSIZE_STDDEF_H -#define _BITSIZE_STDDEF_H - -#define _SIZE_T -typedef unsigned long size_t; -#define _PTRDIFF_T -typedef signed long ptrdiff_t; - -#endif /* _BITSIZE_STDDEF_H */ diff --git a/usr/include/stddef.h b/usr/include/stddef.h index 338b0dd..6811451 100644 --- a/usr/include/stddef.h +++ b/usr/include/stddef.h @@ -9,7 +9,29 @@ # error "__KLIBC__ not defined, compiler invocation error!" #endif -#include <bitsize/stddef.h> +/* + * __SIZE_TYPE__ and __PTRDIFF_TYPE__ are defined by GCC and + * many other compilers to what types the ABI expects on the + * target platform for size_t and ptrdiff_t, so we use these + * for size_t, ssize_t, ptrdiff_t definitions, if available; + * fall back to unsigned long, which is correct on ILP32 and + * LP64 platforms (Linux does not have any others) otherwise. + * + * Note: the order "long unsigned int" precisely matches GCC. + */ +#ifndef __SIZE_TYPE__ +#define __SIZE_TYPE__ long unsigned int +#endif + +#ifndef __PTRDIFF_TYPE__ +#define __PTRDIFF_TYPE__ long int +#endif + +#define _SIZE_T +typedef __SIZE_TYPE__ size_t; + +#define _PTRDIFF_T +typedef __PTRDIFF_TYPE__ ptrdiff_t; #undef NULL #ifdef __cplusplus diff --git a/usr/include/sys/types.h b/usr/include/sys/types.h index 4ad9930..229f7d6 100644 --- a/usr/include/sys/types.h +++ b/usr/include/sys/types.h @@ -10,7 +10,10 @@ #include <stdint.h> #define _SSIZE_T -typedef ptrdiff_t ssize_t; +/* __SIZE_TYPE__ defined either by GCC or <stddef.h> */ +#define unsigned /* nothing, temporarily */ +typedef signed __SIZE_TYPE__ ssize_t; +#undef unsigned #include <linux/posix_types.h> #include <asm/types.h> @@ -41,21 +44,6 @@ typedef __kernel_fsid_t fsid_t; * The following typedefs are also protected by individual ifdefs for * historical reasons: */ -#ifndef _SIZE_T -#define _SIZE_T -typedef __kernel_size_t size_t; -#endif - -#ifndef _SSIZE_T -#define _SSIZE_T -typedef __kernel_ssize_t ssize_t; -#endif - -#ifndef _PTRDIFF_T -#define _PTRDIFF_T -typedef __kernel_ptrdiff_t ptrdiff_t; -#endif - #ifndef _TIME_T #define _TIME_T typedef __kernel_time_t time_t; -- 1.7.10
Hi, I?ve gone through the mailing list archives and hereby want to resubmit my pending patches. Most are independent of each other, except the m68k patch which will only be complete if sigsuspend is also fixed. (It can be applied before that, though.) http://www.zytor.com/pipermail/klibc/2012-January/003173.html [PATCH] fix m68k support Resubmitted here as 0005. While there was a question from Andreas, this WFM as-is and he never responded what else should be used. (And the form I submitted is used by eglibc, too.) http://www.zytor.com/pipermail/klibc/2012-January/003171.html [PATCH] add mkstemp(3) using entropy from ELF aux vector AT_RANDOM Dropped because mksh does not use mkstemp/tempnam any more. http://www.zytor.com/pipermail/klibc/2012-March/003194.html [PATCH 1/3] align __le64 (and other) type definitions with linux-libc-dev headers Resubmitted here as 0001. http://www.zytor.com/pipermail/klibc/2012-March/003195.html [PATCH 2/3] fix missing prototypes for ctype inline functions Resubmitted here as 0002. http://www.zytor.com/pipermail/klibc/2012-March/003193.html [PATCH 3/3] fix missing prototypes for stdio inline functions Dropped because hpa recently added prototypes to the headers, although slightly differently. http://www.zytor.com/pipermail/klibc/2012-May/003201.html [PATCH] fix non-RT sigsuspend() Cleaned up by hpa?s suggestion and resubmitted here as 0003. Please add this, definitely, with high urgency (as klibc?s dash is also affected), until *all* architectures are switched to RT signals. There?s another, new, patch (0004 here), based on a request by hpa: http://www.zytor.com/pipermail/klibc/2012-April/003199.html It changes the way size_t, ssize_t and ptrdiff_t are defined to use the definition from the compiler (GCC and compatibles, such as Clang) with a fallback to long/unsigned long if none is given, which is always correct on LP64 and by-the-size correct on ILP32 platforms. This is mostly for benefit of GCC?s -Wformat so the fallback not being int/unsigned int on some platforms does not hurt. (Besides, klcc invokes gcc, not some-random-compiler. And this is only for stuff compiled with klibc, anyway.) I?ve tested the following things: ? compile klibc (amd64, i386, m68k) ? check for header warnings (amd64) ? build mksh against klibc, both statically and dynamically linked ? amd64, i386: -O2 -g -Wall -Wextra -Wformat ? m68k: -O2 -Wall -Wextra -Wformat ? test mksh (statically and dynamically linked) No errors. \o/ bye, //mirabilos -- I believe no one can invent an algorithm. One just happens to hit upon it when God enlightens him. Or only God invents algorithms, we merely copy them. If you don't believe in God, just consider God as Nature if you won't deny existence. -- Coywolf Qi Hunt
Thorsten Glaser
2012-May-15 17:33 UTC
[klibc] [PATCH 1/5] align __le64 (and other) type definitions with linux-libc-dev headers
Signed-off-by: Thorsten Glaser <tg at mirbsd.org> --- usr/include/sys/types.h | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/usr/include/sys/types.h b/usr/include/sys/types.h index 3a4c738..4ad9930 100644 --- a/usr/include/sys/types.h +++ b/usr/include/sys/types.h @@ -89,16 +89,17 @@ typedef uint16_t u_int16_t; typedef uint32_t u_int32_t; typedef uint64_t u_int64_t; -typedef uint16_t __bitwise __le16; -typedef uint16_t __bitwise __be16; -typedef uint32_t __bitwise __le32; -typedef uint32_t __bitwise __be32; -typedef uint64_t __bitwise __le64; -typedef uint64_t __bitwise __be64; - -typedef uint16_t __sum16; -typedef uint32_t __sum32; -typedef uint64_t __sum64; +typedef __u16 __bitwise __le16; +typedef __u16 __bitwise __be16; +typedef __u32 __bitwise __le32; +typedef __u32 __bitwise __be32; +typedef __u64 __bitwise __le64; +typedef __u64 __bitwise __be64; + +typedef __u16 __bitwise __sum16; +typedef __u32 __bitwise __sum32; +typedef __u64 __bitwise __sum64; +typedef __u32 __bitwise __wsum; #define __aligned_u64 __u64 __attribute__((aligned(8))) #define __aligned_be64 __be64 __attribute__((aligned(8))) -- 1.7.10
Thorsten Glaser
2012-May-15 17:33 UTC
[klibc] [PATCH 2/5] fix missing prototypes for ctype inline functions
Signed-off-by: Thorsten Glaser <tg at mirbsd.org> --- usr/include/ctype.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/usr/include/ctype.h b/usr/include/ctype.h index 4fd162b..14a2f2d 100644 --- a/usr/include/ctype.h +++ b/usr/include/ctype.h @@ -47,6 +47,20 @@ __extern int tolower(int); extern const unsigned char __ctypes[]; +__must_inline int __ctype_isalnum(int); +__must_inline int __ctype_isalpha(int); +__must_inline int __ctype_isascii(int); +__must_inline int __ctype_isblank(int); +__must_inline int __ctype_iscntrl(int); +__must_inline int __ctype_isdigit(int); +__must_inline int __ctype_isgraph(int); +__must_inline int __ctype_islower(int); +__must_inline int __ctype_isprint(int); +__must_inline int __ctype_ispunct(int); +__must_inline int __ctype_isspace(int); +__must_inline int __ctype_isupper(int); +__must_inline int __ctype_isxdigit(int); + __must_inline int __ctype_isalnum(int __c) { return __ctypes[__c + 1] & @@ -118,6 +132,9 @@ __must_inline int __ctype_isxdigit(int __c) #define _toupper(__c) ((__c) & ~32) #define _tolower(__c) ((__c) | 32) +__must_inline int __ctype_toupper(int); +__must_inline int __ctype_tolower(int); + __must_inline int __ctype_toupper(int __c) { return __ctype_islower(__c) ? _toupper(__c) : __c; -- 1.7.10
- fix syscall API and vfork - support 6-argument syscalls - add open/openat special handling for non-regparm arches Signed-off-by: Thorsten Glaser <tg at mirbsd.org> --- usr/klibc/README.klibc | 2 +- usr/klibc/SYSCALLS.def | 4 ++-- usr/klibc/arch/m68k/Kbuild | 1 + usr/klibc/arch/m68k/open.S | 22 +++++++++++++++++++++ usr/klibc/arch/m68k/openat.S | 26 +++++++++++++++++++++++++ usr/klibc/arch/m68k/syscall.S | 42 +++++++++++++++++++++++++++++++++-------- usr/klibc/arch/m68k/vfork.S | 13 ++++--------- usr/klibc/open.c | 2 +- usr/klibc/openat.c | 2 +- 9 files changed, 92 insertions(+), 22 deletions(-) create mode 100644 usr/klibc/arch/m68k/open.S create mode 100644 usr/klibc/arch/m68k/openat.S diff --git a/usr/klibc/README.klibc b/usr/klibc/README.klibc index 8b6e923..d4e4240 100644 --- a/usr/klibc/README.klibc +++ b/usr/klibc/README.klibc @@ -43,7 +43,7 @@ b) If you're cross-compiling, you need to set KLIBCARCH to the i386: Working ia64: Working static, shared untested m32r: Untested - m68k: Untested + m68k: Working m68knommu: Not yet ported mips: Working mips64: Not yet ported diff --git a/usr/klibc/SYSCALLS.def b/usr/klibc/SYSCALLS.def index 7abab15..b45d422 100644 --- a/usr/klibc/SYSCALLS.def +++ b/usr/klibc/SYSCALLS.def @@ -154,8 +154,8 @@ int getcwd::__getcwd(char *, size_t); /* * I/O operations */ -<!i386,64> int open::__open(const char *, int, mode_t); -<?!i386,64> int openat::__openat(int, const char *, int, mode_t); +<!i386,m68k,64> int open::__open(const char *, int, mode_t); +<?!i386,m68k,64> int openat::__openat(int, const char *, int, mode_t); <64> int open(const char *, int, mode_t); ssize_t read(int, void *, size_t); ssize_t write(int, const void *, size_t); diff --git a/usr/klibc/arch/m68k/Kbuild b/usr/klibc/arch/m68k/Kbuild index 8d6137c..d56ae0e 100644 --- a/usr/klibc/arch/m68k/Kbuild +++ b/usr/klibc/arch/m68k/Kbuild @@ -3,6 +3,7 @@ # klib-y := setjmp.o syscall.o vfork.o +klib-y += open.o openat.o always := crt0.o targets := crt0.o diff --git a/usr/klibc/arch/m68k/open.S b/usr/klibc/arch/m68k/open.S new file mode 100644 index 0000000..c9a7ee3 --- /dev/null +++ b/usr/klibc/arch/m68k/open.S @@ -0,0 +1,22 @@ +/* + * arch/m68k/open.S + * + * Handle the open() system call - oddball due to the varadic + * prototype, which forces the use of the cdecl calling convention, + * and the need for O_LARGEFILE. + */ + +#include <asm/unistd.h> + +/* <asm/fcntl.h>, despite the name, isn't assembly-safe */ +#define O_LARGEFILE 0400000 + + .globl open + .type open, at function + +open: + or.l # O_LARGEFILE, 8(%sp) + move.l # __NR_open, %d0 + br __syscall_common + + .size open,.-open diff --git a/usr/klibc/arch/m68k/openat.S b/usr/klibc/arch/m68k/openat.S new file mode 100644 index 0000000..25d8a1a --- /dev/null +++ b/usr/klibc/arch/m68k/openat.S @@ -0,0 +1,26 @@ +/* + * arch/m68k/openat.S + * + * Handle the openat() system call - oddball due to the varadic + * prototype, which forces the use of the cdecl calling convention, + * and the need for O_LARGEFILE. + */ + +#include <asm/unistd.h> + +/* <asm/fcntl.h>, despite the name, isn't assembly-safe */ +#define O_LARGEFILE 0400000 + +#ifdef __NR_openat /* Don't build if kernel headers too old */ + + .globl openat + .type openat, at function + +openat: + or.l # O_LARGEFILE, 12(%sp) + move.l # __NR_openat, %d0 + br __syscall_common + + .size openat,.-openat + +#endif diff --git a/usr/klibc/arch/m68k/syscall.S b/usr/klibc/arch/m68k/syscall.S index 966c92d..c909e2a 100644 --- a/usr/klibc/arch/m68k/syscall.S +++ b/usr/klibc/arch/m68k/syscall.S @@ -11,17 +11,43 @@ .globl __syscall_common .type __syscall_common, @function __syscall_common: - movem.l %d2-%d6, -(%sp) /* 5 registers saved */ - movem.l 24(%sp), %d1-%d6 + /* + * According to eglibc, separate moves are faster than movem; + * speed is important and this code is not duplicated anyway, + * so we do the same here. We use %a1 as scratch register for + * saving; syscall arguments are to be in %d1 to %d5 and %a0. + */ + move.l 24(%sp), %a0 /* orig.sp+24: arg 6 */ + move.l %d5, -(%sp) /* push d5 (callee saved) */ + move.l 24(%sp), %d5 /* orig.sp+20: arg 5 */ + move.l %d4, -(%sp) /* push d4 (callee saved) */ + move.l 24(%sp), %d4 /* orig.sp+16: arg 4 */ + move.l %d3, -(%sp) /* push d3 (callee saved) */ + move.l 24(%sp), %d3 /* orig.sp+12: arg 3 */ + move.l %d2, %a1 /* save d2 (callee saved) in a1 */ + move.l 20(%sp), %d2 /* orig.sp+8: arg 2 */ + move.l 16(%sp), %d1 /* orig.sp+4: arg 1 */ trap #0 - cmpi.l #-4095, %d0 - blt.l 1f + move.l %a1, %d2 /* restore d2 from a1 (scratch) */ + move.l (%sp)+, %d3 /* pop d3..d5, see above */ + move.l (%sp)+, %d4 + move.l (%sp)+, %d5 + + /* syscall is done, result in %d0, registers are restored */ + .globl __syscall_checkandout +__syscall_checkandout: + /* now check for error */ + cmp.l #-4095, %d0 + bcs.l 1f /* jump if _not_ error */ + + /* prepare for error return */ neg.l %d0 move.l %d0, (errno) - moveq #-1, %d0 -1: - movea.l %d0, %a0 /* Redundant return */ - movem.l (%sp)+, %d2-%d6 /* Restore registers */ + move.l #-1, %d0 + /* fallthrough into common return path */ + +1: /* copy return value to %a0 for syscalls returning pointers */ + move.l %d0, %a0 rts .size __syscall_common,.-__syscall_common diff --git a/usr/klibc/arch/m68k/vfork.S b/usr/klibc/arch/m68k/vfork.S index a3a7e44..98170a6 100644 --- a/usr/klibc/arch/m68k/vfork.S +++ b/usr/klibc/arch/m68k/vfork.S @@ -15,14 +15,9 @@ vfork: move.l (%sp)+, %d1 /* Return address */ move.l # __NR_vfork, %d0 trap #0 - move.l %d1, -(%sp) - cmpi.l #-4095, %d0 - blt.l 1f - neg.l %d0 - move.l %d0, (errno) - moveq #-1, %d0 -1: - movea.l %d0, %a0 - rts + move.l %d1, -(%sp) /* restore stack */ + + /* fallthrough into common code from syscall.S */ + bra __syscall_checkandout .size vfork, .-vfork diff --git a/usr/klibc/open.c b/usr/klibc/open.c index 9b0897a..126f6db 100644 --- a/usr/klibc/open.c +++ b/usr/klibc/open.c @@ -10,7 +10,7 @@ #include <fcntl.h> #include <bitsize.h> -#if _BITSIZE == 32 && !defined(__i386__) +#if _BITSIZE == 32 && !defined(__i386__) && !defined(__m68k__) extern int __open(const char *, int, mode_t); diff --git a/usr/klibc/openat.c b/usr/klibc/openat.c index 83c87cd..8e5baa0 100644 --- a/usr/klibc/openat.c +++ b/usr/klibc/openat.c @@ -10,7 +10,7 @@ #include <fcntl.h> #include <bitsize.h> -#if _BITSIZE == 32 && !defined(__i386__) && defined(__NR_openat) +#if _BITSIZE == 32 && !defined(__i386__) && !defined(__m68k__) && defined(__NR_openat) extern int __openat(int, const char *, int, mode_t); -- 1.7.10