Commit 1c59d383 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'linux-kselftest-nolibc-6.6-rc1' of...

Merge tag 'linux-kselftest-nolibc-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest

Pull nolibc updates from Shuah Khan:
 "Nolibc:
   - improved portability by removing build errors with -ENOSYS
   - added syscall6() on MIPS to support pselect6() and mmap()
   - added setvbuf(), rmdir(), pipe(), pipe2()
   - add support for ppc/ppc64
   - environ is no longer optional
   - fixed frame pointer issues at -O0
   - dropped sys_stat() in favor of sys_statx()
   - centralized _start_c() to remove lots of asm code
   - switched size_t to __SIZE_TYPE__

  Selftests:
   - improved status reporting (success/warning/failure counts, path to
     log file)
   - various code cleanups (indent, unused variables, ...)
   - more consistent test numbering
   - enabled compiler warnings
   - dropped unreliable chmod_net test
   - improved reliability (create /dev/zero & /tmp, rely less on /proc)
   - new tests (brk/sbrk/mmap/munmap)
   - improved compatibility with musl
   - new run-nolibc-test target to build and run natively
   - new run-libc-test target to build and run against native libc
   - made the cmdline parser more reliable against boolean arguments
   - dropped dependency on memfd for vfprintf() test
   - nolibc-test is no longer stripped
   - added support for extending ARCH via XARCH

  Other:
   - add Thomas as co-maintainer"

* tag 'linux-kselftest-nolibc-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: (103 commits)
  tools/nolibc: avoid undesired casts in the __sysret() macro
  tools/nolibc: keep brk(), sbrk(), mmap() away from __sysret()
  tools/nolibc: silence ppc64 compile warnings
  selftests/nolibc: libc-test: use HOSTCC instead of CC
  tools/nolibc: stackprotector.h: make __stack_chk_init static
  selftests/nolibc: allow report with existing test log
  selftests/nolibc: add test support for ppc64
  selftests/nolibc: add test support for ppc64le
  selftests/nolibc: add test support for ppc
  selftests/nolibc: add XARCH and ARCH mapping support
  tools/nolibc: add support for powerpc64
  tools/nolibc: add support for powerpc
  MAINTAINERS: nolibc: add myself as co-maintainer
  selftests/nolibc: enable compiler warnings
  selftests/nolibc: don't strip nolibc-test
  selftests/nolibc: prevent out of bounds access in expect_vfprintf
  selftests/nolibc: use correct return type for read() and write()
  selftests/nolibc: avoid sign-compare warnings
  selftests/nolibc: avoid unused parameter warnings
  selftests/nolibc: make functions static if possible
  ...
parents 815c24a0 556fb713
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -15010,6 +15010,7 @@ F: include/linux/power/bq27xxx_battery.h
NOLIBC HEADER FILE
M:	Willy Tarreau <w@1wt.eu>
M:	Thomas Weißschuh <linux@weissschuh.net>
S:	Maintained
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/wtarreau/nolibc.git
F:	tools/include/nolibc/
+1 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ nolibc_arch := $(patsubst arm64,aarch64,$(ARCH))
arch_file := arch-$(nolibc_arch).h
all_files := \
		compiler.h \
		crt.h \
		ctype.h \
		errno.h \
		nolibc.h \
+19 −66
Original line number Diff line number Diff line
@@ -8,34 +8,7 @@
#define _NOLIBC_ARCH_AARCH64_H

#include "compiler.h"

/* The struct returned by the newfstatat() syscall. Differs slightly from the
 * x86_64's stat one by field ordering, so be careful.
 */
struct sys_stat_struct {
	unsigned long   st_dev;
	unsigned long   st_ino;
	unsigned int    st_mode;
	unsigned int    st_nlink;
	unsigned int    st_uid;
	unsigned int    st_gid;

	unsigned long   st_rdev;
	unsigned long   __pad1;
	long            st_size;
	int             st_blksize;
	int             __pad2;

	long            st_blocks;
	long            st_atime;
	unsigned long   st_atime_nsec;
	long            st_mtime;

	unsigned long   st_mtime_nsec;
	long            st_ctime;
	unsigned long   st_ctime_nsec;
	unsigned int    __unused[2];
};
#include "crt.h"

/* Syscalls for AARCH64 :
 *   - registers are 64-bit
@@ -171,33 +144,13 @@ struct sys_stat_struct {
	_arg1;                                                                \
})

char **environ __attribute__((weak));
const unsigned long *_auxv __attribute__((weak));

/* startup code */
void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __no_stack_protector _start(void)
void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_stack_protector _start(void)
{
	__asm__ volatile (
#ifdef _NOLIBC_STACKPROTECTOR
		"bl __stack_chk_init\n"   /* initialize stack protector                     */
#endif
		"ldr x0, [sp]\n"     /* argc (x0) was in the stack                          */
		"add x1, sp, 8\n"    /* argv (x1) = sp                                      */
		"lsl x2, x0, 3\n"    /* envp (x2) = 8*argc ...                              */
		"add x2, x2, 8\n"    /*           + 8 (skip null)                           */
		"add x2, x2, x1\n"   /*           + argv                                    */
		"adrp x3, environ\n"          /* x3 = &environ (high bits)                  */
		"str x2, [x3, #:lo12:environ]\n" /* store envp into environ                 */
		"mov x4, x2\n"       /* search for auxv (follows NULL after last env)       */
		"0:\n"
		"ldr x5, [x4], 8\n"  /* x5 = *x4; x4 += 8                                   */
		"cbnz x5, 0b\n"      /* and stop at NULL after last env                     */
		"adrp x3, _auxv\n"   /* x3 = &_auxv (high bits)                             */
		"str x4, [x3, #:lo12:_auxv]\n" /* store x4 into _auxv                       */
		"and sp, x1, -16\n"  /* sp must be 16-byte aligned in the callee            */
		"bl main\n"          /* main() returns the status code, we'll exit with it. */
		"mov x8, 93\n"       /* NR_exit == 93                                       */
		"svc #0\n"
		"mov x0, sp\n"          /* save stack pointer to x0, as arg1 of _start_c */
		"and sp, x0, -16\n"     /* sp must be 16-byte aligned in the callee      */
		"bl  _start_c\n"        /* transfer to c runtime                         */
	);
	__builtin_unreachable();
}
+20 −91
Original line number Diff line number Diff line
@@ -8,43 +8,7 @@
#define _NOLIBC_ARCH_ARM_H

#include "compiler.h"

/* The struct returned by the stat() syscall, 32-bit only, the syscall returns
 * exactly 56 bytes (stops before the unused array). In big endian, the format
 * differs as devices are returned as short only.
 */
struct sys_stat_struct {
#if defined(__ARMEB__)
	unsigned short st_dev;
	unsigned short __pad1;
#else
	unsigned long  st_dev;
#endif
	unsigned long  st_ino;
	unsigned short st_mode;
	unsigned short st_nlink;
	unsigned short st_uid;
	unsigned short st_gid;

#if defined(__ARMEB__)
	unsigned short st_rdev;
	unsigned short __pad2;
#else
	unsigned long  st_rdev;
#endif
	unsigned long  st_size;
	unsigned long  st_blksize;
	unsigned long  st_blocks;

	unsigned long  st_atime;
	unsigned long  st_atime_nsec;
	unsigned long  st_mtime;
	unsigned long  st_mtime_nsec;

	unsigned long  st_ctime;
	unsigned long  st_ctime_nsec;
	unsigned long  __unused[2];
};
#include "crt.h"

/* Syscalls for ARM in ARM or Thumb modes :
 *   - registers are 32-bit
@@ -220,49 +184,14 @@ struct sys_stat_struct {
	_arg1;                                                                \
})


char **environ __attribute__((weak));
const unsigned long *_auxv __attribute__((weak));

/* startup code */
void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __no_stack_protector _start(void)
void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_stack_protector _start(void)
{
	__asm__ volatile (
#ifdef _NOLIBC_STACKPROTECTOR
		"bl __stack_chk_init\n"       /* initialize stack protector                          */
#endif
		"pop {%r0}\n"                 /* argc was in the stack                               */
		"mov %r1, %sp\n"              /* argv = sp                                           */

		"add %r2, %r0, $1\n"          /* envp = (argc + 1) ...                               */
		"lsl %r2, %r2, $2\n"          /*        * 4        ...                               */
		"add %r2, %r2, %r1\n"         /*        + argv                                       */
		"ldr %r3, 1f\n"               /* r3 = &environ (see below)                           */
		"str %r2, [r3]\n"             /* store envp into environ                             */

		"mov r4, r2\n"                /* search for auxv (follows NULL after last env)       */
		"0:\n"
		"mov r5, r4\n"                /* r5 = r4                                             */
		"add r4, r4, #4\n"            /* r4 += 4                                             */
		"ldr r5,[r5]\n"               /* r5 = *r5 = *(r4-4)                                  */
		"cmp r5, #0\n"                /* and stop at NULL after last env                     */
		"bne 0b\n"
		"ldr %r3, 2f\n"               /* r3 = &_auxv (low bits)                              */
		"str r4, [r3]\n"              /* store r4 into _auxv                                 */

		"mov %r3, $8\n"               /* AAPCS : sp must be 8-byte aligned in the            */
		"neg %r3, %r3\n"              /*         callee, and bl doesn't push (lr=pc)         */
		"and %r3, %r3, %r1\n"         /* so we do sp = r1(=sp) & r3(=-8);                    */
		"mov %sp, %r3\n"

		"bl main\n"                   /* main() returns the status code, we'll exit with it. */
		"movs r7, $1\n"               /* NR_exit == 1                                        */
		"svc $0x00\n"
		".align 2\n"                  /* below are the pointers to a few variables           */
		"1:\n"
		".word environ\n"
		"2:\n"
		".word _auxv\n"
		"mov %r0, sp\n"         /* save stack pointer to %r0, as arg1 of _start_c */
		"and ip, %r0, #-8\n"    /* sp must be 8-byte aligned in the callee        */
		"mov sp, ip\n"
		"bl  _start_c\n"        /* transfer to c runtime                          */
	);
	__builtin_unreachable();
}
+20 −66
Original line number Diff line number Diff line
@@ -8,32 +8,7 @@
#define _NOLIBC_ARCH_I386_H

#include "compiler.h"

/* The struct returned by the stat() syscall, 32-bit only, the syscall returns
 * exactly 56 bytes (stops before the unused array).
 */
struct sys_stat_struct {
	unsigned long  st_dev;
	unsigned long  st_ino;
	unsigned short st_mode;
	unsigned short st_nlink;
	unsigned short st_uid;
	unsigned short st_gid;

	unsigned long  st_rdev;
	unsigned long  st_size;
	unsigned long  st_blksize;
	unsigned long  st_blocks;

	unsigned long  st_atime;
	unsigned long  st_atime_nsec;
	unsigned long  st_mtime;
	unsigned long  st_mtime_nsec;

	unsigned long  st_ctime;
	unsigned long  st_ctime_nsec;
	unsigned long  __unused[2];
};
#include "crt.h"

/* Syscalls for i386 :
 *   - mostly similar to x86_64
@@ -180,9 +155,6 @@ struct sys_stat_struct {
	_eax;							\
})

char **environ __attribute__((weak));
const unsigned long *_auxv __attribute__((weak));

/* startup code */
/*
 * i386 System V ABI mandates:
@@ -190,33 +162,15 @@ const unsigned long *_auxv __attribute__((weak));
 * 2) The deepest stack frame should be set to zero
 *
 */
void __attribute__((weak,noreturn,optimize("omit-frame-pointer"))) __no_stack_protector _start(void)
void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_stack_protector _start(void)
{
	__asm__ volatile (
#ifdef _NOLIBC_STACKPROTECTOR
		"call __stack_chk_init\n"   /* initialize stack protector                    */
#endif
		"pop %eax\n"                /* argc   (first arg, %eax)                      */
		"mov %esp, %ebx\n"          /* argv[] (second arg, %ebx)                     */
		"lea 4(%ebx,%eax,4),%ecx\n" /* then a NULL then envp (third arg, %ecx)       */
		"mov %ecx, environ\n"       /* save environ                                  */
		"xor  %ebp, %ebp\n"       /* zero the stack frame                                */
		"mov %ecx, %edx\n"          /* search for auxv (follows NULL after last env) */
		"0:\n"
		"add $4, %edx\n"            /* search for auxv using edx, it follows the     */
		"cmp -4(%edx), %ebp\n"      /* ... NULL after last env (ebp is zero here)    */
		"jnz 0b\n"
		"mov %edx, _auxv\n"         /* save it into _auxv                            */
		"and $-16, %esp\n"          /* x86 ABI : esp must be 16-byte aligned before  */
		"sub $4, %esp\n"            /* the call instruction (args are aligned)       */
		"push %ecx\n"               /* push all registers on the stack so that we    */
		"push %ebx\n"               /* support both regparm and plain stack modes    */
		"push %eax\n"
		"call main\n"               /* main() returns the status code in %eax        */
		"mov %eax, %ebx\n"          /* retrieve exit code (32-bit int)               */
		"movl $1, %eax\n"           /* NR_exit == 1                                  */
		"int $0x80\n"               /* exit now                                      */
		"hlt\n"                     /* ensure it does not                            */
		"mov  %esp, %eax\n"       /* save stack pointer to %eax, as arg1 of _start_c     */
		"and  $-16, %esp\n"       /* last pushed argument must be 16-byte aligned        */
		"push %eax\n"             /* push arg1 on stack to support plain stack modes too */
		"call _start_c\n"         /* transfer to c runtime                               */
		"hlt\n"                   /* ensure it does not return                           */
	);
	__builtin_unreachable();
}
Loading