mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-27 12:57:53 +00:00
Fixes for nolibc for v6.2
This series addresses the following bugs: o The fd_set structure was incorrectly defined as arrays of u32 instead of long, which breaks BE64. Fix courtesy of Sven Schnelle. o S_ISxxx macros were incorrectly testing the bits after applying them instead of bitwise ANDing S_FMT with the value. Fix from Warner Losh. o The mips code was randomly broken due to an unprotected "noreorder" directive in the _start code that could prevent the assembler from filling delayed slots. This in turn resulted in random other instructions being placed into those slots. Fix courtesy of Willy Tarreau. o The current nolibc header layout refrains from including files that are not explicitly included by the code using nolibc. Unfortunately, this causes build failures when such files contain definitions that are used (for example) by libgcc. Example definitions include raise() and memset(), which are called by some architectures, but only at certain optimization levels. Fix courtesy of Willy Tarreau. o gcc 11.3 in ARM thumb2 mode at -O2 recognized a memset() construction inside the memset() definition. The compiler replaced this construction with a call to... memset(). Userland cannot be forced to build with -ffreestanding, so an empty asm() statement was introduced into the loop the loop in order to prevent the compiler from making this unproductive transformation. Fix courtesy of Willy Tarreau. o Most of the O_* macros were wrong on RISCV because their octal values were coded as hexadecimal. This resulted in the getdents64() selftest failing. Fix courtesy of Willy Tarreau. The series was tested on x86_64, i386, armv5, armv7, thumb1, thumb2, mips and riscv, all at -O0, -Os and -O3. -----BEGIN PGP SIGNATURE----- iQJHBAABCgAxFiEEbK7UrM+RBIrCoViJnr8S83LZ+4wFAmO8ZPsTHHBhdWxtY2tA a2VybmVsLm9yZwAKCRCevxLzctn7jDqUD/4zymVYzv0Pfbr3gHiZAgWCr+FwHz46 SGK4KVvSPn3L0MMT0JW+Ws6tB/WKwOFzK4dtvhU+z1ClLZEhLgQVVjo9lwLvUorj QvxubMnRLJCZjyvgCOJ2mbJCGLMSoOceSrNgl4xEeQ1gu6wrmjLu8erDJvBCyTMX 4Io7tv1ddO3xJuptrJzB1jZpFl/OvJkrSuB3fHAtCcc/YcXy59imp690lawyWfLL ryiwVgep0XRPLTiEm+Jd0iMsTFJaJEEvkt2aQ9yd6C92z27/+erJ7SsrWcXHZAjD Ck7h4EX2SpJliRFW4QeGdC5/16/7EIGs2WUTuGnwB4uIleD4vGwwvNJkclhKi2au vKfcy5/soFuaWfOOUthfHAA0OX4DXHGFWP9BhEljGTG0F9bbGqqXnsZm37qrq2cQ Ns2tQ2BXvm6qY1TGsv3usMch8xF3Gy521iO5qMQ1YYMeB8Jw6IZJnT6w0gHSqo8O mR8i2zgnsvc3a2KTs45djdN4cu7ARzwwGDXc+ZgEhOsVGp5k93MGoixdYjZkIzCp Zoy/p9sr66OTeUXfxVOJvJcnXzAlWTUgWu92+tlDDrhu2S+YWRGDqhjUfjnqM+dt q7EYj/tVmXsy5B/f/ndmjTUwCxQ7oDM3v72YqGbrUFdA7lHeNSkWY1kjM4PmRJsr aZBwnA0Utly0VQ== =bR/q -----END PGP SIGNATURE----- Merge tag 'urgent-nolibc.2023.01.09a' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu Pull nolibc fixes from Paul McKenney: - The fd_set structure was incorrectly defined as arrays of u32 instead of long, which breaks BE64. Fix courtesy of Sven Schnelle. - S_ISxxx macros were incorrectly testing the bits after applying them instead of bitwise ANDing S_FMT with the value. Fix from Warner Losh. - The mips code was randomly broken due to an unprotected "noreorder" directive in the _start code that could prevent the assembler from filling delayed slots. This in turn resulted in random other instructions being placed into those slots. Fix courtesy of Willy Tarreau. - The current nolibc header layout refrains from including files that are not explicitly included by the code using nolibc. Unfortunately, this causes build failures when such files contain definitions that are used (for example) by libgcc. Example definitions include raise() and memset(), which are called by some architectures, but only at certain optimization levels. Fix courtesy of Willy Tarreau. - gcc 11.3 in ARM thumb2 mode at -O2 recognized a memset() construction inside the memset() definition. The compiler replaced this construction with a call to... memset(). Userland cannot be forced to build with -ffreestanding, so an empty asm() statement was introduced into the loop the loop in order to prevent the compiler from making this unproductive transformation. Fix courtesy of Willy Tarreau. - Most of the O_* macros were wrong on RISCV because their octal values were coded as hexadecimal. This resulted in the getdents64() selftest failing. Fix courtesy of Willy Tarreau. This was tested on x86_64, i386, armv5, armv7, thumb1, thumb2, mips and riscv, all at -O0, -Os and -O3. * tag 'urgent-nolibc.2023.01.09a' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu: tools/nolibc: fix the O_* fcntl/open macro definitions for riscv tools/nolibc: prevent gcc from making memset() loop over itself tools/nolibc: fix missing includes causing build issues at -O0 tools/nolibc: restore mips branch ordering in the _start block tools/nolibc: Fix S_ISxxx macros nolibc: fix fd_set type
This commit is contained in:
commit
f129b61612
12 changed files with 79 additions and 38 deletions
|
@ -192,6 +192,7 @@ struct sys_stat_struct {
|
|||
__asm__ (".section .text\n"
|
||||
".weak __start\n"
|
||||
".set nomips16\n"
|
||||
".set push\n"
|
||||
".set noreorder\n"
|
||||
".option pic0\n"
|
||||
".ent __start\n"
|
||||
|
@ -210,6 +211,7 @@ __asm__ (".section .text\n"
|
|||
"li $v0, 4001\n" // NR_exit == 4001
|
||||
"syscall\n"
|
||||
".end __start\n"
|
||||
".set pop\n"
|
||||
"");
|
||||
|
||||
#endif // _NOLIBC_ARCH_MIPS_H
|
||||
|
|
|
@ -11,13 +11,13 @@
|
|||
#define O_RDONLY 0
|
||||
#define O_WRONLY 1
|
||||
#define O_RDWR 2
|
||||
#define O_CREAT 0x100
|
||||
#define O_EXCL 0x200
|
||||
#define O_NOCTTY 0x400
|
||||
#define O_TRUNC 0x1000
|
||||
#define O_APPEND 0x2000
|
||||
#define O_NONBLOCK 0x4000
|
||||
#define O_DIRECTORY 0x200000
|
||||
#define O_CREAT 0x40
|
||||
#define O_EXCL 0x80
|
||||
#define O_NOCTTY 0x100
|
||||
#define O_TRUNC 0x200
|
||||
#define O_APPEND 0x400
|
||||
#define O_NONBLOCK 0x800
|
||||
#define O_DIRECTORY 0x10000
|
||||
|
||||
struct sys_stat_struct {
|
||||
unsigned long st_dev; /* Device. */
|
||||
|
|
|
@ -96,4 +96,7 @@ int ispunct(int c)
|
|||
return isgraph(c) && !isalnum(c);
|
||||
}
|
||||
|
||||
/* make sure to include all global symbols */
|
||||
#include "nolibc.h"
|
||||
|
||||
#endif /* _NOLIBC_CTYPE_H */
|
||||
|
|
|
@ -24,4 +24,7 @@ static int errno;
|
|||
*/
|
||||
#define MAX_ERRNO 4095
|
||||
|
||||
/* make sure to include all global symbols */
|
||||
#include "nolibc.h"
|
||||
|
||||
#endif /* _NOLIBC_ERRNO_H */
|
||||
|
|
|
@ -19,4 +19,7 @@ int raise(int signal)
|
|||
return sys_kill(sys_getpid(), signal);
|
||||
}
|
||||
|
||||
/* make sure to include all global symbols */
|
||||
#include "nolibc.h"
|
||||
|
||||
#endif /* _NOLIBC_SIGNAL_H */
|
||||
|
|
|
@ -303,4 +303,7 @@ void perror(const char *msg)
|
|||
fprintf(stderr, "%s%serrno=%d\n", (msg && *msg) ? msg : "", (msg && *msg) ? ": " : "", errno);
|
||||
}
|
||||
|
||||
/* make sure to include all global symbols */
|
||||
#include "nolibc.h"
|
||||
|
||||
#endif /* _NOLIBC_STDIO_H */
|
||||
|
|
|
@ -419,4 +419,7 @@ char *u64toa(uint64_t in)
|
|||
return itoa_buffer;
|
||||
}
|
||||
|
||||
/* make sure to include all global symbols */
|
||||
#include "nolibc.h"
|
||||
|
||||
#endif /* _NOLIBC_STDLIB_H */
|
||||
|
|
|
@ -88,8 +88,11 @@ void *memset(void *dst, int b, size_t len)
|
|||
{
|
||||
char *p = dst;
|
||||
|
||||
while (len--)
|
||||
while (len--) {
|
||||
/* prevent gcc from recognizing memset() here */
|
||||
asm volatile("");
|
||||
*(p++) = b;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
@ -285,4 +288,7 @@ char *strrchr(const char *s, int c)
|
|||
return (char *)ret;
|
||||
}
|
||||
|
||||
/* make sure to include all global symbols */
|
||||
#include "nolibc.h"
|
||||
|
||||
#endif /* _NOLIBC_STRING_H */
|
||||
|
|
|
@ -1243,5 +1243,7 @@ ssize_t write(int fd, const void *buf, size_t count)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* make sure to include all global symbols */
|
||||
#include "nolibc.h"
|
||||
|
||||
#endif /* _NOLIBC_SYS_H */
|
||||
|
|
|
@ -25,4 +25,7 @@ time_t time(time_t *tptr)
|
|||
return tv.tv_sec;
|
||||
}
|
||||
|
||||
/* make sure to include all global symbols */
|
||||
#include "nolibc.h"
|
||||
|
||||
#endif /* _NOLIBC_TIME_H */
|
||||
|
|
|
@ -26,13 +26,13 @@
|
|||
#define S_IFSOCK 0140000
|
||||
#define S_IFMT 0170000
|
||||
|
||||
#define S_ISDIR(mode) (((mode) & S_IFDIR) == S_IFDIR)
|
||||
#define S_ISCHR(mode) (((mode) & S_IFCHR) == S_IFCHR)
|
||||
#define S_ISBLK(mode) (((mode) & S_IFBLK) == S_IFBLK)
|
||||
#define S_ISREG(mode) (((mode) & S_IFREG) == S_IFREG)
|
||||
#define S_ISFIFO(mode) (((mode) & S_IFIFO) == S_IFIFO)
|
||||
#define S_ISLNK(mode) (((mode) & S_IFLNK) == S_IFLNK)
|
||||
#define S_ISSOCK(mode) (((mode) & S_IFSOCK) == S_IFSOCK)
|
||||
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
||||
#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
|
||||
#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
|
||||
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
|
||||
#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
|
||||
#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
|
||||
#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
|
||||
|
||||
/* dirent types */
|
||||
#define DT_UNKNOWN 0x0
|
||||
|
@ -89,39 +89,46 @@
|
|||
#define EXIT_SUCCESS 0
|
||||
#define EXIT_FAILURE 1
|
||||
|
||||
#define FD_SETIDXMASK (8 * sizeof(unsigned long))
|
||||
#define FD_SETBITMASK (8 * sizeof(unsigned long)-1)
|
||||
|
||||
/* for select() */
|
||||
typedef struct {
|
||||
uint32_t fd32[(FD_SETSIZE + 31) / 32];
|
||||
unsigned long fds[(FD_SETSIZE + FD_SETBITMASK) / FD_SETIDXMASK];
|
||||
} fd_set;
|
||||
|
||||
#define FD_CLR(fd, set) do { \
|
||||
fd_set *__set = (set); \
|
||||
int __fd = (fd); \
|
||||
if (__fd >= 0) \
|
||||
__set->fd32[__fd / 32] &= ~(1U << (__fd & 31)); \
|
||||
#define FD_CLR(fd, set) do { \
|
||||
fd_set *__set = (set); \
|
||||
int __fd = (fd); \
|
||||
if (__fd >= 0) \
|
||||
__set->fds[__fd / FD_SETIDXMASK] &= \
|
||||
~(1U << (__fd & FX_SETBITMASK)); \
|
||||
} while (0)
|
||||
|
||||
#define FD_SET(fd, set) do { \
|
||||
fd_set *__set = (set); \
|
||||
int __fd = (fd); \
|
||||
if (__fd >= 0) \
|
||||
__set->fd32[__fd / 32] |= 1U << (__fd & 31); \
|
||||
#define FD_SET(fd, set) do { \
|
||||
fd_set *__set = (set); \
|
||||
int __fd = (fd); \
|
||||
if (__fd >= 0) \
|
||||
__set->fds[__fd / FD_SETIDXMASK] |= \
|
||||
1 << (__fd & FD_SETBITMASK); \
|
||||
} while (0)
|
||||
|
||||
#define FD_ISSET(fd, set) ({ \
|
||||
fd_set *__set = (set); \
|
||||
int __fd = (fd); \
|
||||
int __r = 0; \
|
||||
if (__fd >= 0) \
|
||||
__r = !!(__set->fd32[__fd / 32] & 1U << (__fd & 31)); \
|
||||
__r; \
|
||||
#define FD_ISSET(fd, set) ({ \
|
||||
fd_set *__set = (set); \
|
||||
int __fd = (fd); \
|
||||
int __r = 0; \
|
||||
if (__fd >= 0) \
|
||||
__r = !!(__set->fds[__fd / FD_SETIDXMASK] & \
|
||||
1U << (__fd & FD_SET_BITMASK)); \
|
||||
__r; \
|
||||
})
|
||||
|
||||
#define FD_ZERO(set) do { \
|
||||
fd_set *__set = (set); \
|
||||
int __idx; \
|
||||
for (__idx = 0; __idx < (FD_SETSIZE+31) / 32; __idx ++) \
|
||||
__set->fd32[__idx] = 0; \
|
||||
#define FD_ZERO(set) do { \
|
||||
fd_set *__set = (set); \
|
||||
int __idx; \
|
||||
int __size = (FD_SETSIZE+FD_SETBITMASK) / FD_SETIDXMASK;\
|
||||
for (__idx = 0; __idx < __size; __idx++) \
|
||||
__set->fds[__idx] = 0; \
|
||||
} while (0)
|
||||
|
||||
/* for poll() */
|
||||
|
@ -202,4 +209,7 @@ struct stat {
|
|||
})
|
||||
#endif
|
||||
|
||||
/* make sure to include all global symbols */
|
||||
#include "nolibc.h"
|
||||
|
||||
#endif /* _NOLIBC_TYPES_H */
|
||||
|
|
|
@ -51,4 +51,7 @@ int tcsetpgrp(int fd, pid_t pid)
|
|||
return ioctl(fd, TIOCSPGRP, &pid);
|
||||
}
|
||||
|
||||
/* make sure to include all global symbols */
|
||||
#include "nolibc.h"
|
||||
|
||||
#endif /* _NOLIBC_UNISTD_H */
|
||||
|
|
Loading…
Reference in a new issue