git-updates
authorGNU Libc Maintainers <debian-glibc@lists.debian.org>
Mon, 11 May 2020 00:04:03 +0000 (01:04 +0100)
committerSamuel Thibault <sthibault@debian.org>
Mon, 11 May 2020 00:04:03 +0000 (01:04 +0100)
GIT update of https://sourceware.org/git/glibc.git/release/2.30/master from glibc-2.30

GIT update of https://sourceware.org/git/glibc.git/release/2.30/master from glibc-2.30

Gbp-Pq: Name git-updates.diff

108 files changed:
ChangeLog
NEWS
bits/utmp.h
configure
configure.ac
debug/tst-backtrace5.c
elf/dl-tunables.list
libio/oldstdfiles.c
localedata/locales/bo_CN
localedata/locales/ug_CN
localedata/locales/zh_CN
login/Makefile
login/getutent_r.c
login/getutid_r.c
login/getutline_r.c
login/getutmp.c
login/getutmpx.c
login/login.c
login/logout.c
login/logwtmp.c
login/programs/utmpdump.c
login/tst-pututxline-cache.c [new file with mode: 0644]
login/tst-pututxline-lockfail.c [new file with mode: 0644]
login/tst-updwtmpx.c [new file with mode: 0644]
login/tst-utmp.c
login/updwtmp.c
login/utmp-private.h
login/utmp_file.c
login/utmpname.c
malloc/Makefile
malloc/arena.c
malloc/malloc.c
malloc/malloc.h
malloc/tst-mallocfork2.c
malloc/tst-mxfast.c [new file with mode: 0644]
malloc/tst-pvalloc-fortify.c [new file with mode: 0644]
misc/sys/cdefs.h
posix/glob.c
stdlib/Makefile
stdlib/tst-system.c
string/string.h
string/test-strstr.c
support/shell-container.c
sysdeps/alpha/fpu/libm-test-ulps
sysdeps/arm/be/nofpu/Implies [new file with mode: 0644]
sysdeps/arm/le/nofpu/Implies [new file with mode: 0644]
sysdeps/generic/not-cancel.h
sysdeps/generic/utmp-equal.h
sysdeps/gnu/bits/utmp.h [deleted file]
sysdeps/gnu/bits/utmpx.h
sysdeps/hppa/dl-fptr.c
sysdeps/hppa/dl-machine.h
sysdeps/hppa/dl-runtime.c [new file with mode: 0644]
sysdeps/hppa/dl-trampoline.S
sysdeps/hppa/fpu/libm-test-ulps
sysdeps/i386/sysdep.h
sysdeps/ieee754/ldbl-96/Makefile
sysdeps/ieee754/ldbl-96/e_rem_pio2l.c
sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c [new file with mode: 0644]
sysdeps/posix/system.c
sysdeps/powerpc/powerpc32/backtrace.c
sysdeps/powerpc/powerpc64/backtrace.c
sysdeps/s390/dl-procinfo.c
sysdeps/s390/dl-procinfo.h
sysdeps/s390/strstr-arch13.S
sysdeps/unix/alpha/getegid.S [deleted file]
sysdeps/unix/alpha/geteuid.S [deleted file]
sysdeps/unix/alpha/getppid.S [deleted file]
sysdeps/unix/getlogin_r.c
sysdeps/unix/sysv/linux/Makefile
sysdeps/unix/sysv/linux/Versions
sysdeps/unix/sysv/linux/alpha/getegid.S [new file with mode: 0644]
sysdeps/unix/sysv/linux/alpha/geteuid.S [new file with mode: 0644]
sysdeps/unix/sysv/linux/alpha/getppid.S [new file with mode: 0644]
sysdeps/unix/sysv/linux/bits/statx.h
sysdeps/unix/sysv/linux/hppa/atomic-machine.h
sysdeps/unix/sysv/linux/hppa/clone.S
sysdeps/unix/sysv/linux/microblaze/sysdep.h
sysdeps/unix/sysv/linux/mips/Makefile
sysdeps/unix/sysv/linux/mips/configure
sysdeps/unix/sysv/linux/mips/configure.ac
sysdeps/unix/sysv/linux/mips/mips32/mips-syscall5.S
sysdeps/unix/sysv/linux/mips/mips32/mips-syscall6.S
sysdeps/unix/sysv/linux/mips/mips32/mips-syscall7.S
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall.h
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall0.c
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall1.c
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall2.c
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall3.c
sysdeps/unix/sysv/linux/mips/mips32/mips16/mips16-syscall4.c
sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h
sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h
sysdeps/unix/sysv/linux/mips/mips64/syscall.S
sysdeps/unix/sysv/linux/not-cancel.h
sysdeps/unix/sysv/linux/pread64_nocancel.c [new file with mode: 0644]
sysdeps/unix/sysv/linux/riscv/sysdep.h
sysdeps/unix/sysv/linux/riscv/vfork.S
sysdeps/unix/sysv/linux/s390/bits/utmp.h
sysdeps/unix/sysv/linux/s390/bits/utmpx.h
sysdeps/unix/sysv/linux/sparc/Makefile
sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c
sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S [new file with mode: 0644]
sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c
sysdeps/unix/sysv/linux/sparc/sparc64/sigreturn_stub.S [new file with mode: 0644]
sysdeps/unix/sysv/linux/test-errno-linux.c
sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h
time/Makefile

index cdb9e14881715711685d5f16515ec1f76729c82b..bc2f4aae69dc25d17214c5c3205fe3b25b0ab701 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,214 @@
+2019-08-15  Florian Weimer  <fweimer@redhat.com>
+
+       [BZ #24899]
+       * sysdeps/gnu/bits/utmpx.h (struct utmpx): Add
+       __attribute_nonstring__ to ut_line, ut_id, ut_user, ut_host.
+       * sysdeps/unix/sysv/linux/s390/bits/utmpx.h (struct utmpx):
+       Likewise.
+       * sysdeps/gnu/bits/utmp.h (struct utmp): Add
+       __attribute_nonstring__ to ut_id.
+       * sysdeps/unix/sysv/linux/s390/bits/utmpx.h (struct utmp):
+       Likewise.
+
+2019-08-28  Florian Weimer  <fweimer@redhat.com>
+
+       [BZ #24902]
+       * login/Makefile (tests): Add tst-pututxline-lockfail.
+       (tst-pututxline-lockfail): Link with -lpthread.
+       * login/utmp_file.c (internal_getut_r): Remove buffer argument.
+       (__libc_getutid_r): Adjust.
+       (__libc_pututline): Likewise.  Check for file_offset == -1.
+       * login/tst-pututxline-lockfail.c: New file.
+
+2019-08-15  Florian Weimer  <fweimer@redhat.com>
+
+       [BZ #24880]
+       * login/utmp_file.c (file_locking_failed): Use struct flock64.
+       (file_locking_unlock): Likewise.
+
+2019-08-15  Florian Weimer  <fweimer@redhat.com>
+
+       [BZ #24879]
+       login: Disarm timer after utmp lock acquisition.
+       * login/utmp_file.c (struct file_locking): Remove.
+       (try_file_lock): Adjust.
+       (file_lock_restore): Remove function.
+       (__libc_getutent_r): .
+       (internal_getut_r): Likewise.
+       (__libc_getutline_r): Likewise.
+       (__libc_pututline): Likewise.
+       (__libc_updwtmp): Likewise.
+
+2019-08-15  Florian Weimer  <fweimer@redhat.com>
+
+       * login/utmp_file.c (__libc_updwtmp): Unlock the right file
+       descriptor.
+       * login/Makefile (tests): Add tst-updwtmpx.
+       * login/tst-updwtmpx.c: New file.
+
+2019-08-13  Florian Weimer  <fweimer@redhat.com>
+
+       * login/utmp_file.c (LOCK_FILE, LOCKING_FAILED, UNLOCK_FILE):
+       Remove macros.
+       (struct file_locking): New.
+       (try_file_lock, file_unlock, file_lock_restore): New functions.
+       (__libc_getutent_r): Use the new functions.
+       (internal_getut_r): Likewise.
+       (__libc_getutline_r): Likewise.
+       (__libc_pututline): Likewise.
+       (__libc_updwtmp): Likewise.
+
+2019-08-13  Florian Weimer  <fweimer@redhat.com>
+
+       * login/getutid_r.c (__getutid_r): _HAVE_UT_ID and _HAVE_UT_TYPE
+       are always true.
+       * login/getutmp.c (getutmp): _HAVE_UT_TYPE, _HAVE_UT_PID,
+       _HAVE_UT_ID, _HAVE_UT_HOST, _HAVE_UT_TV are always true.
+       * login/getutmpx.c (getutmpx): Likewise.
+       * login/login.c (login): _HAVE_UT_TYPE, _HAVE_UT_PID are always
+       true.
+       * login/logout.c (logout): _HAVE_UT_TYPE, _HAVE_UT_HOST,
+       _HAVE_UT_TV are always true.
+       * login/logwtmp.c (logwtmp): _HAVE_UT_PID, _HAVE_UT_TYPE,
+       _HAVE_UT_HOST, _HAVE_UT_TV are always true.
+       * login/tst-utmp.c: _HAVE_UT_TYPE, _HAVE_UT_TV are always true.
+       * login/utmp_file.c (__libc_setutent): _HAVE_UT_TYPE, _HAVE_UT_ID
+       are always true.
+       (internal_getut_r): _HAVE_UT_TYPE is always true.
+       (__libc_pututline): Likewise.
+       * login/programs/utmpdump.c (print_entry): Assume that
+       _HAVE_UT_TYPE, _HAVE_UT_PID, _HAVE_UT_ID, _HAVE_UT_HOST,
+       _HAVE_UT_TV are always true.
+       * sysdeps/generic/utmp-equal.h (__utmp_equal): _HAVE_UT_TYPE,
+       _HAVE_UT_ID are always true.
+       * sysdeps/gnu/bits/utmp.h: Move to ...
+       * bits/utmp.h: ... here, replacing the old file.
+
+2019-08-05  Florian Weimer  <fweimer@redhat.com>
+
+       [BZ #23518]
+       * login/uptmp-private.h (struct ufuncs): Remove definition.
+       (__libc_utmp_file_functions, __libc_utmp_unknown_functions)
+       (__libc_utmp_jump_table): Remove declarations.
+       (__libc_setutent, __libc_getutent_r, __libc_getutid_r)
+       (__libc_getutline_r, __libc_pututline, __libc_endutent)
+       (__libc_updwtmp): Declare.
+       * login/getutent_r.c (__libc_utmp_unknown_functions)
+       (__libc_utmp_jump_table, setutent_unknown, getutent_r_unknown)
+       (getutid_r_unknown, getutline_r_unknown, pututline_unknown)
+       (endutent_unknown): Remove definitions.
+       (__setutent): Call __libc_setutent.
+       (__getutent_r): Call __libc_getutent_r.
+       (__pututline): Call __libc_pututline.
+       (__endutent): Call __libc_endutent.
+       * login/getutid_r.c (__getutid_r): Call __libc_getutid_r.
+       * login/getutline_r.c (__getutline_r): Call __libc_getutline_r.
+       * login/updwtmp.c (__updwtmp): Call __libc_updwtmp.
+       * login/utmp_file.c (__libc_utmp_file_functions): Remove definition
+       (__libc_setutent): Rename from stetutent_file.  Drop static.
+       (maybe_setutent): New function.
+       (__libc_getutent_r): Rename from getutent_r_file.  Drop static.
+       Check for initialization.
+       (__libc_getutid_r): Rename from getutid_r_file.  Drop static.
+       Check for initialization.
+       (__libc_getutline_r): Rename from getutline_r_file.  Drop static.
+       Check for initialization.
+       (__libc_pututline): Rename from pututline_file.  Drop static.
+       Check for initialization.
+       (__libc_endutent): Rename from endutent_file.  Drop static.  Check
+       for initialization.
+       (__libc_updwtmp): Rename from updwtmp_file.  Drop static.
+       * login/utmpname.c (__utmpname): Call __libc_endutent.
+       * sysdeps/unix/getlogin_r (__getlogin_r): Call __libc_setutent,
+       __libc_getutlien_r, __libc_endutent.
+       * manual/users.texi (Who Logged In, Manipulating the Database):
+       Adjust.
+
+2019-08-15  Florian Weimer  <fweimer@redhat.com>
+
+       * malloc/Makefile (tests): Only add tst-mxfast for
+       $(have-tunables).
+       * malloc/tst-mxfast.c: Fix copyright year.
+       (do_test): Fix GNU style issues.  Use TEST_COMPARE instead of
+       assert for checks.
+
+2019-08-09  DJ Delorie  <dj@redhat.com>
+
+       * elf/dl-tunables.list: Add glibc.malloc.mxfast.
+       * manual/tunables.texi: Document it.
+       * malloc/malloc.c (do_set_mxfast): New.
+       (__libc_mallopt): Call it.
+       * malloc/arena.c: Add mxfast tunable.
+       * malloc/tst-mxfast.c: New.
+       * malloc/Makefile: Add it.
+
+2019-08-08  Niklas Hambüchen  <mail@nh2.me>
+           Carlos O'Donell  <carlos@redhat.com>
+
+       [BZ #24026]
+       * malloc/malloc.c (__malloc_info): Account for top chunk.
+
+2019-11-01  Dragan Mladjenovic  <dmladjenovic@wavecomp.com>
+
+       * sysdeps/unix/sysv/linux/mips/Makefile
+       (test-xfail-check-execstack):
+       Move under mips-has-gnustack != yes.
+       (CFLAGS-.o*, ASFLAGS-.o*): New rules.
+       Apply -Wa,-execstack if mips-force-execstack == yes.
+       * sysdeps/unix/sysv/linux/mips/configure: Regenerated.
+       * sysdeps/unix/sysv/linux/mips/configure.ac
+       (mips-force-execstack): New var.
+       Set to yes for hard-float builds with minimum_kernel < 4.8.0
+       or minimum_kernel not set at all.
+       (mips-has-gnustack): New var.
+       Use value of libc_cv_as_noexecstack
+       if mips-force-execstack != yes, otherwise set to no.
+
+2019-10-08  Gabriel F. T. Gomes  <gabrielftg@linux.ibm.com>
+
+       * Makefile: Fix locale dependency for a couple of tests.
+       ($(objpfx)tst-strftime2.out): New rule.
+       ($(objpfx)tst-strftime3.out): Likewise.
+
+2019-09-20  Joseph Myers  <joseph@codesourcery.com>
+
+       * sysdeps/unix/sysv/linux/riscv/vfork.S: Do not include
+       <linux/sched.h>.
+       (CLONE_VM): New macro.
+       (CLONE_VFORK): Likewise.
+
+2019-09-14  Aurelien Jarno  <aurelien@aurel32.net>
+
+       [BZ #24986]
+        * sysdeps/unix/alpha/getegid.S: Move to ...
+       * sysdeps/unix/sysv/linux/alpha/getegid.S: ... here.
+        * sysdeps/unix/alpha/geteuid.S: Move to ...
+       * sysdeps/unix/sysv/linux/alpha/geteuid.S: ... here.
+        * sysdeps/unix/alpha/getppid.S: Move to ...
+       * sysdeps/unix/sysv/linux/alpha/getppid.S: ... here
+
+2019-09-08  Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+       * sysdeps/hppa/fpu/libm-test-ulps: Update.
+
+2019-09-03  Aurelien Jarno  <aurelien@aurel32.net>
+
+       * sysdeps/alpha/fpu/libm-test-ulps: Regenerated using GCC 9.2.
+
+2019-08-28  Rafal Luzynski  <digitalfreak@lingonborough.com>
+
+       [BZ #24682]
+       * NEWS: Mention this bug fixed.
+       * localedata/locales/bo_CN (first_weekday): Add, set to 2 (Monday).
+       * localedata/locales/ug_CN (first_weekday): Likewise.
+       * localedata/locales/zh_CN (first_weekday): Likewise.
+
+2019-08-01  Florian Weimer  <fweimer@redhat.com>
+
+       [BZ #24867]
+       * malloc/malloc.c (__malloc_info): Remove unwanted leading
+       whitespace.
+
 2019-08-01  Carlos O'Donell <carlos@redhat.com>
 
        * version.h (RELEASE): Set to "stable".
diff --git a/NEWS b/NEWS
index ee9ed4de5a3f28a7cd6a882c82fe89cf3f68e2f7..a2911177c3fc113a92b67e61a934375240ab21ee 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,54 @@ See the end for copying conditions.
 
 Please send GNU C library bug reports via <https://sourceware.org/bugzilla/>
 using `glibc' in the "product" field.
+\f
+Version 2.30.1
+
+Security related changes:
+
+CVE-2019-19126: ld.so failed to ignore the LD_PREFER_MAP_32BIT_EXEC
+  environment variable during program execution after a security
+  transition, allowing local attackers to restrict the possible mapping
+  addresses for loaded libraries and thus bypass ASLR for a setuid
+  program.  Reported by Marcin KoÅ›cielnicki.
+
+CVE-2020-10029: Trigonometric functions on x86 targets suffered from stack
+  corruption when they were passed a pseudo-zero argument.  Reported by Guido
+  Vranken / ForAllSecure Mayhem.
+
+CVE-2020-1751: A defect in the PowerPC backtrace function could cause an
+  out-of-bounds write when executed in a signal frame context.
+
+CVE-2020-1752: A use-after-free vulnerability in the glob function when
+  expanding ~user has been fixed.
+
+The following bugs are resolved with this release:
+
+  [20543] Please move from .gnu.linkonce to comdat
+  [23296] Data race in setting function descriptor during lazy binding
+  [23518] login: Remove utmp backend jump tables
+  [24682] localedata: zh_CN first weekday should be Monday per GB/T
+    7408-2005
+  [24867] malloc: Remove unwanted leading whitespace in malloc_info
+  [24879] login: Disarm timer after utmp lock acquisition
+  [24880] login: Use struct flock64 in utmp
+  [24882] login: Acquire write lock early in pututline
+  [24986] alpha: new getegid, geteuid and getppid syscalls used
+    unconditionally
+  [24899] login: Add nonstring attributes to struct utmp, struct utmpx
+  [24902] login: pututxline could fail to overwrite existing entries
+  [25066] FAIL: nptl/tst-tls1 on hppa
+  [25189] Don't use a custom wrapper macro around __has_include
+  [25203] libio: Disable vtable validation for pre-2.1 interposed handles
+  [25204] Ignore LD_PREFER_MAP_32BIT_EXEC for SUID programs
+  [25225] ld.so fails to link on x86 if GCC defaults to -fcf-protection
+  [25232] No const correctness for strchr et al. for Clang++
+  [25401] Remove incorrect alloc_size attribute from pvalloc
+  [25487] sinl() stack corruption from crafted input (CVE-2020-10029)
+  [25523] MIPS/Linux inline syscall template is miscompiled
+  [25635] arm: Wrong sysdep order selection for soft-fp
+  [25715] system() returns wrong errors when posix_spawn fails
+
 \f
 Version 2.30
 
index 4c36ca19ce02135bb3777cc6a06039351637ac6c..854b342164b785e06aa72d0b8775f6fd0bf5b2a8 100644 (file)
@@ -1,4 +1,4 @@
-/* The `struct utmp' type, describing entries in the utmp file.  Generic/BSDish
+/* The `struct utmp' type, describing entries in the utmp file.
    Copyright (C) 1993-2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
 #endif
 
 #include <paths.h>
-#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <bits/wordsize.h>
 
 
-#define        UT_NAMESIZE     8
-#define        UT_LINESIZE     8
-#define        UT_HOSTSIZE     16
+#define UT_LINESIZE    32
+#define UT_NAMESIZE    32
+#define UT_HOSTSIZE    256
 
 
+/* The structure describing an entry in the database of
+   previous logins.  */
 struct lastlog
   {
-    time_t ll_time;
+#if __WORDSIZE_TIME64_COMPAT32
+    int32_t ll_time;
+#else
+    __time_t ll_time;
+#endif
     char ll_line[UT_LINESIZE];
     char ll_host[UT_HOSTSIZE];
   };
 
-struct utmp
+
+/* The structure describing the status of a terminated process.  This
+   type is used in `struct utmp' below.  */
+struct exit_status
   {
-    char ut_line[UT_LINESIZE];
-    char ut_user[UT_NAMESIZE];
-#define ut_name ut_user
-    char ut_host[UT_HOSTSIZE];
-    long int ut_time;
+    short int e_termination;   /* Process termination status.  */
+    short int e_exit;          /* Process exit status.  */
   };
 
 
-#define _HAVE_UT_HOST 1                /* We have the ut_host field.  */
+/* The structure describing an entry in the user accounting database.  */
+struct utmp
+{
+  short int ut_type;           /* Type of login.  */
+  pid_t ut_pid;                        /* Process ID of login process.  */
+  char ut_line[UT_LINESIZE]
+    __attribute_nonstring__;   /* Devicename.  */
+  char ut_id[4]
+    __attribute_nonstring__;   /* Inittab ID.  */
+  char ut_user[UT_NAMESIZE]
+    __attribute_nonstring__;   /* Username.  */
+  char ut_host[UT_HOSTSIZE]
+    __attribute_nonstring__;   /* Hostname for remote login.  */
+  struct exit_status ut_exit;  /* Exit status of a process marked
+                                  as DEAD_PROCESS.  */
+/* The ut_session and ut_tv fields must be the same size when compiled
+   32- and 64-bit.  This allows data files and shared memory to be
+   shared between 32- and 64-bit applications.  */
+#if __WORDSIZE_TIME64_COMPAT32
+  int32_t ut_session;          /* Session ID, used for windowing.  */
+  struct
+  {
+    int32_t tv_sec;            /* Seconds.  */
+    int32_t tv_usec;           /* Microseconds.  */
+  } ut_tv;                     /* Time entry was made.  */
+#else
+  long int ut_session;         /* Session ID, used for windowing.  */
+  struct timeval ut_tv;                /* Time entry was made.  */
+#endif
+
+  int32_t ut_addr_v6[4];       /* Internet address of remote host.  */
+  char __glibc_reserved[20];           /* Reserved for future use.  */
+};
+
+/* Backwards compatibility hacks.  */
+#define ut_name                ut_user
+#ifndef _NO_UT_TIME
+/* We have a problem here: `ut_time' is also used otherwise.  Define
+   _NO_UT_TIME if the compiler complains.  */
+# define ut_time       ut_tv.tv_sec
+#endif
+#define ut_xtime       ut_tv.tv_sec
+#define ut_addr                ut_addr_v6[0]
+
+
+/* Values for the `ut_type' field of a `struct utmp'.  */
+#define EMPTY          0       /* No valid user accounting information.  */
+
+#define RUN_LVL                1       /* The system's runlevel.  */
+#define BOOT_TIME      2       /* Time of system boot.  */
+#define NEW_TIME       3       /* Time after system clock changed.  */
+#define OLD_TIME       4       /* Time when system clock changed.  */
+
+#define INIT_PROCESS   5       /* Process spawned by the init process.  */
+#define LOGIN_PROCESS  6       /* Session leader of a logged in user.  */
+#define USER_PROCESS   7       /* Normal process.  */
+#define DEAD_PROCESS   8       /* Terminated process.  */
+
+#define ACCOUNTING     9
+
+/* Old Linux name for the EMPTY type.  */
+#define UT_UNKNOWN     EMPTY
+
+
+/* Tell the user that we have a modern system with UT_HOST, UT_PID,
+   UT_TYPE, UT_ID and UT_TV fields.  */
+#define _HAVE_UT_TYPE  1
+#define _HAVE_UT_PID   1
+#define _HAVE_UT_ID    1
+#define _HAVE_UT_TV    1
+#define _HAVE_UT_HOST  1
index c773c487b542b3beb12fa2c70c8ea123b7bee5cd..83ae6899c54acd302ab9cd764efee209860498bc 100755 (executable)
--- a/configure
+++ b/configure
@@ -3777,11 +3777,32 @@ else
 fi
 
 
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+#ifndef __CET__
+#error no CET compiler support
+#endif
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  libc_cv_compiler_default_cet=yes
+else
+  libc_cv_compiler_default_cet=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
 # Check whether --enable-cet was given.
 if test "${enable_cet+set}" = set; then :
   enableval=$enable_cet; enable_cet=$enableval
 else
-  enable_cet=no
+  enable_cet=$libc_cv_compiler_default_cet
 fi
 
 
@@ -4014,7 +4035,7 @@ if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \
            -o conftest conftest.S 1>&5 2>&5; then
   # Do a link to see if the backend supports IFUNC relocs.
   $READELF -r conftest 1>&5
-  LC_ALL=C $READELF -r conftest | grep 'no relocations' >/dev/null || {
+  LC_ALL=C $READELF -Wr conftest | grep -q 'IRELATIVE\|R_SPARC_JMP_IREL' && {
     libc_cv_ld_gnu_indirect_function=yes
   }
 fi
index 598ba6c4aed08a3bcced95577a39c48dfef69dc1..51b85359ee84c19357b938aa6c4c498484dd9b6d 100644 (file)
@@ -472,11 +472,18 @@ AC_ARG_ENABLE([mathvec],
              [build_mathvec=$enableval],
              [build_mathvec=notset])
 
+AC_TRY_COMPILE([], [
+#ifndef __CET__
+# error no CET compiler support
+#endif],
+              [libc_cv_compiler_default_cet=yes],
+              [libc_cv_compiler_default_cet=no])
+
 AC_ARG_ENABLE([cet],
              AC_HELP_STRING([--enable-cet],
                             [enable Intel Control-flow Enforcement Technology (CET), x86 only]),
              [enable_cet=$enableval],
-             [enable_cet=no])
+             [enable_cet=$libc_cv_compiler_default_cet])
 
 # We keep the original values in `$config_*' and never modify them, so we
 # can write them unchanged into config.make.  Everything else uses
@@ -641,7 +648,7 @@ if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \
            -o conftest conftest.S 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD; then
   # Do a link to see if the backend supports IFUNC relocs.
   $READELF -r conftest 1>&AS_MESSAGE_LOG_FD
-  LC_ALL=C $READELF -r conftest | grep 'no relocations' >/dev/null || {
+  LC_ALL=C $READELF -Wr conftest | grep -q 'IRELATIVE\|R_SPARC_JMP_IREL' && {
     libc_cv_ld_gnu_indirect_function=yes
   }
 fi
index 5a5ce8bc79bc65ee7e79983f8dd0d642c431c532..aed5ee4c94c7e8233c3f55281665d090df596279 100644 (file)
@@ -89,6 +89,18 @@ handle_signal (int signum)
       }
   /* Symbol names are not available for static functions, so we do not
      check do_test.  */
+
+  /* Check that backtrace does not return more than what fits in the array
+     (bug 25423).  */
+  for (int j = 0; j < NUM_FUNCTIONS; j++)
+    {
+      n = backtrace (addresses, j);
+      if (n > j)
+       {
+         FAIL ();
+         return;
+       }
+    }
 }
 
 NO_INLINE int
index 1fc2d8886b306de98bd149c0dae1758635b22fec..525c3767b5e2872fff1ed229c154878787240cf7 100644 (file)
@@ -85,6 +85,11 @@ glibc {
     tcache_unsorted_limit {
       type: SIZE_T
     }
+    mxfast {
+      type: SIZE_T
+      minval: 0
+      security_level: SXID_IGNORE
+    }
   }
   cpu {
     hwcap_mask {
index 2b861cd754986831e2d49a7ccb98a35e6501e729..7503cdd62dfd502c1de6704dc675fcf62673fe9c 100644 (file)
@@ -83,6 +83,11 @@ _IO_check_libio (void)
        = stderr->_vtable_offset =
        ((int) sizeof (struct _IO_FILE)
         - (int) sizeof (struct _IO_FILE_complete));
+
+      if (_IO_stdin_.vtable != &_IO_old_file_jumps
+         || _IO_stdout_.vtable != &_IO_old_file_jumps
+         || _IO_stderr_.vtable != &_IO_old_file_jumps)
+       IO_set_accept_foreign_vtables (&_IO_vtable_check);
     }
 }
 
index 90cbc7807b9da4423a48547604d3822f8cd5d9d3..9df91a172180737c281d2ae999d12733233f4161 100644 (file)
@@ -128,6 +128,7 @@ t_fmt_ampm        "<U0F46><U0F74><U0F0B><U0F5A><U0F7C><U0F51>/
 <U0025><U0070>"
 
 week 7;19971130;1
+first_weekday 2
 END LC_TIME
 
 LC_MESSAGES
index 1ba583c588e074d2131f3fcee10c3a324174c57a..83d15c90e489bf39ea8e92c39e1bcc2b7811ddb0 100644 (file)
@@ -165,6 +165,7 @@ am_pm    "";""
 date_fmt "%a<U060C> %d-%m-%Y<U060C> %T"
 
 week 7;19971130;1
+first_weekday 2
 END LC_TIME
 
 LC_MESSAGES
index 62a46415c1567ed38d58140312cef11eed46092c..cd4b33602aa0114a471d23f5a5c5f9fdc98c854d 100644 (file)
@@ -139,6 +139,7 @@ t_fmt_ampm "%p %I<U65F6>%M<U5206>%S<U79D2>"
 
 date_fmt       "%Y<U5E74> %m<U6708> %d<U65E5> %A %H:%M:%S %Z"
 week 7;19971130;1
+first_weekday 2
 END LC_TIME
 
 LC_MESSAGES
index 92535f0aec2ce8be35e64349247f78fb0fd04fc9..4fd8195e7316cbf812fba667514e9eaab7caa1bb 100644 (file)
@@ -43,7 +43,8 @@ endif
 subdir-dirs = programs
 vpath %.c programs
 
-tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin
+tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \
+  tst-pututxline-lockfail tst-pututxline-cache
 
 # Build the -lutil library with these extra functions.
 extra-libs      := libutil
@@ -71,3 +72,6 @@ endif
 $(inst_libexecdir)/pt_chown: $(objpfx)pt_chown $(+force)
        $(make-target-directory)
        -$(INSTALL_PROGRAM) -m 4755 -o root $< $@
+
+$(objpfx)tst-pututxline-lockfail: $(shared-thread-library)
+$(objpfx)tst-pututxline-cache: $(shared-thread-library)
index 98ffc5d1c6561f1e1dc1077a41c6238338901c21..fd13be8a1e009f8ea4042b8a5b11cc0b65e5f039 100644 (file)
 
 #include "utmp-private.h"
 
-
-/* Functions defined here.  */
-static int setutent_unknown (void);
-static int getutent_r_unknown (struct utmp *buffer, struct utmp **result);
-static int getutid_r_unknown (const struct utmp *line, struct utmp *buffer,
-                             struct utmp **result);
-static int getutline_r_unknown (const struct utmp *id, struct utmp *buffer,
-                               struct utmp **result);
-static struct utmp *pututline_unknown (const struct utmp *data);
-static void endutent_unknown (void);
-
-/* Initial Jump table.  */
-const struct utfuncs __libc_utmp_unknown_functions =
-{
-  setutent_unknown,
-  getutent_r_unknown,
-  getutid_r_unknown,
-  getutline_r_unknown,
-  pututline_unknown,
-  endutent_unknown,
-  NULL
-};
-
-/* Currently selected backend.  */
-const struct utfuncs *__libc_utmp_jump_table = &__libc_utmp_unknown_functions;
-
 /* We need to protect the opening of the file.  */
 __libc_lock_define_initialized (, __libc_utmp_lock attribute_hidden)
 
 
-static int
-setutent_unknown (void)
-{
-  int result;
-
-  result = (*__libc_utmp_file_functions.setutent) ();
-  if (result)
-    __libc_utmp_jump_table = &__libc_utmp_file_functions;
-
-  return result;
-}
-
-
-static int
-getutent_r_unknown (struct utmp *buffer, struct utmp **result)
-{
-  /* The backend was not yet initialized.  */
-  if (setutent_unknown ())
-    return (*__libc_utmp_jump_table->getutent_r) (buffer, result);
-
-  /* Not available.  */
-  *result = NULL;
-  return -1;
-}
-
-
-static int
-getutid_r_unknown (const struct utmp *id, struct utmp *buffer,
-                  struct utmp **result)
-{
-  /* The backend was not yet initialized.  */
-  if (setutent_unknown ())
-    return (*__libc_utmp_jump_table->getutid_r) (id, buffer, result);
-
-  /* Not available.  */
-  *result = NULL;
-  return -1;
-}
-
-
-static int
-getutline_r_unknown (const struct utmp *line, struct utmp *buffer,
-                    struct utmp **result)
-{
-  /* The backend was not yet initialized.  */
-  if (setutent_unknown ())
-    return (*__libc_utmp_jump_table->getutline_r) (line, buffer, result);
-
-  /* Not available.  */
-  *result = NULL;
-  return -1;
-}
-
-
-static struct utmp *
-pututline_unknown (const struct utmp *data)
-{
-  /* The backend was not yet initialized.  */
-  if (setutent_unknown ())
-    return (*__libc_utmp_jump_table->pututline) (data);
-
-  /* Not available.  */
-  return NULL;
-}
-
-
-static void
-endutent_unknown (void)
-{
-  /* Nothing to do.  */
-}
-
-
 void
 __setutent (void)
 {
   __libc_lock_lock (__libc_utmp_lock);
 
-  (*__libc_utmp_jump_table->setutent) ();
+  __libc_setutent ();
 
   __libc_lock_unlock (__libc_utmp_lock);
 }
@@ -145,7 +46,7 @@ __getutent_r (struct utmp *buffer, struct utmp **result)
 
   __libc_lock_lock (__libc_utmp_lock);
 
-  retval = (*__libc_utmp_jump_table->getutent_r) (buffer, result);
+  retval = __libc_getutent_r (buffer, result);
 
   __libc_lock_unlock (__libc_utmp_lock);
 
@@ -162,7 +63,7 @@ __pututline (const struct utmp *data)
 
   __libc_lock_lock (__libc_utmp_lock);
 
-  buffer = (*__libc_utmp_jump_table->pututline) (data);
+  buffer = __libc_pututline (data);
 
   __libc_lock_unlock (__libc_utmp_lock);
 
@@ -177,8 +78,7 @@ __endutent (void)
 {
   __libc_lock_lock (__libc_utmp_lock);
 
-  (*__libc_utmp_jump_table->endutent) ();
-  __libc_utmp_jump_table = &__libc_utmp_unknown_functions;
+  __libc_endutent ();
 
   __libc_lock_unlock (__libc_utmp_lock);
 }
index 34ea61d8f4a3455a26ad7e29d525bdc0de343b98..460d94be0cb5ecf9f5fea1765888c7bb46abfee7 100644 (file)
@@ -32,7 +32,6 @@ __libc_lock_define (extern, __libc_utmp_lock attribute_hidden)
 int
 __getutid_r (const struct utmp *id, struct utmp *buffer, struct utmp **result)
 {
-#if (_HAVE_UT_ID - 0) && (_HAVE_UT_TYPE - 0)
   int retval;
 
   /* Test whether ID has any of the legal types.  */
@@ -49,15 +48,11 @@ __getutid_r (const struct utmp *id, struct utmp *buffer, struct utmp **result)
 
   __libc_lock_lock (__libc_utmp_lock);
 
-  retval = (*__libc_utmp_jump_table->getutid_r) (id, buffer, result);
+  retval = __libc_getutid_r (id, buffer, result);
 
   __libc_lock_unlock (__libc_utmp_lock);
 
   return retval;
-#else  /* !_HAVE_UT_ID && !_HAVE_UT_TYPE */
-  __set_errno (ENOSYS);
-  return -1;
-#endif
 }
 libc_hidden_def (__getutid_r)
 weak_alias (__getutid_r, getutid_r)
index 110b89e43818ea97a0c0ae023f188a8fca37f767..f03255dbbdd2a545e22534ab124ab2e1e16b7ebc 100644 (file)
@@ -36,7 +36,7 @@ __getutline_r (const struct utmp *line, struct utmp *buffer,
 
   __libc_lock_lock (__libc_utmp_lock);
 
-  retval = (*__libc_utmp_jump_table->getutline_r) (line, buffer, result);
+  retval = __libc_getutline_r (line, buffer, result);
 
   __libc_lock_unlock (__libc_utmp_lock);
 
index 73bc15d781760f758d0798c5897e24c9fa002168..4e3be11216a5875848b3b6f63c7b14a2b37fa479 100644 (file)
 void
 getutmp (const struct utmpx *utmpx, struct utmp *utmp)
 {
-#if _HAVE_UT_TYPE - 0
   utmp->ut_type = utmpx->ut_type;
-#endif
-#if _HAVE_UT_PID - 0
   utmp->ut_pid = utmpx->ut_pid;
-#endif
   memcpy (utmp->ut_line, utmpx->ut_line, sizeof (utmp->ut_line));
   memcpy (utmp->ut_user, utmpx->ut_user, sizeof (utmp->ut_user));
-#if _HAVE_UT_ID - 0
   memcpy (utmp->ut_id, utmpx->ut_id, sizeof (utmp->ut_id));
-#endif
-#if _HAVE_UT_HOST - 0
   memcpy (utmp->ut_host, utmpx->ut_host, sizeof (utmp->ut_host));
-#endif
-#if _HAVE_UT_TV - 0
   utmp->ut_tv = utmpx->ut_tv;
-#else
-  utmp->ut_time = utmpx->ut_time;
-#endif
 }
index b181d9bc30ffa845eb19ee38cb387c9842ee6a4c..da28d339abf991c3320834267dcee3200aa43a0b 100644 (file)
@@ -24,24 +24,11 @@ void
 getutmpx (const struct utmp *utmp, struct utmpx *utmpx)
 {
   memset (utmpx, 0, sizeof (struct utmpx));
-
-#if _HAVE_UT_TYPE - 0
   utmpx->ut_type = utmp->ut_type;
-#endif
-#if _HAVE_UT_PID - 0
   utmpx->ut_pid = utmp->ut_pid;
-#endif
   memcpy (utmpx->ut_line, utmp->ut_line, sizeof (utmp->ut_line));
   memcpy (utmpx->ut_user, utmp->ut_user, sizeof (utmp->ut_user));
-#if _HAVE_UT_ID - 0
   memcpy (utmpx->ut_id, utmp->ut_id, sizeof (utmp->ut_id));
-#endif
-#if _HAVE_UT_HOST - 0
   memcpy (utmpx->ut_host, utmp->ut_host, sizeof (utmp->ut_host));
-#endif
-#if _HAVE_UT_TV - 0
   utmpx->ut_tv = utmp->ut_tv;
-#else
-  utmpx->ut_time = utmp->ut_time;
-#endif
 }
index 09ef3f75a5328d380835a17e4bfa41dd817096e7..b7d638c692cb456fa1b4440e79a603f73b10701b 100644 (file)
@@ -91,12 +91,8 @@ login (const struct utmp *ut)
   struct utmp copy = *ut;
 
   /* Fill in those fields we supply.  */
-#if _HAVE_UT_TYPE - 0
   copy.ut_type = USER_PROCESS;
-#endif
-#if _HAVE_UT_PID - 0
   copy.ut_pid = getpid ();
-#endif
 
   /* Seek tty.  */
   found_tty = tty_name (STDIN_FILENO, &tty, sizeof (_tty));
index 85254d03248d246d68c08a38a0cb746bbf904859..5015c1af0b7383005193a4ac4c383cfb5db89652 100644 (file)
@@ -36,9 +36,7 @@ logout (const char *line)
   setutent ();
 
   /* Fill in search information.  */
-#if _HAVE_UT_TYPE - 0
   tmp.ut_type = USER_PROCESS;
-#endif
   strncpy (tmp.ut_line, line, sizeof tmp.ut_line);
 
   /* Read the record.  */
@@ -46,20 +44,12 @@ logout (const char *line)
     {
       /* Clear information about who & from where.  */
       memset (ut->ut_name, '\0', sizeof ut->ut_name);
-#if _HAVE_UT_HOST - 0
       memset (ut->ut_host, '\0', sizeof ut->ut_host);
-#endif
-#if _HAVE_UT_TV - 0
       struct timeval tv;
       __gettimeofday (&tv, NULL);
       ut->ut_tv.tv_sec = tv.tv_sec;
       ut->ut_tv.tv_usec = tv.tv_usec;
-#else
-      ut->ut_time = time (NULL);
-#endif
-#if _HAVE_UT_TYPE - 0
       ut->ut_type = DEAD_PROCESS;
-#endif
 
       if (pututline (ut) != NULL)
        result = 1;
index f53187121c4ccb28f2a1ccffe03051a3d027e71b..50d14976c7141f71d215b7f16ad6ed2e3415142c 100644 (file)
@@ -30,26 +30,16 @@ logwtmp (const char *line, const char *name, const char *host)
 
   /* Set information in new entry.  */
   memset (&ut, 0, sizeof (ut));
-#if _HAVE_UT_PID - 0
   ut.ut_pid = getpid ();
-#endif
-#if _HAVE_UT_TYPE - 0
   ut.ut_type = name[0] ? USER_PROCESS : DEAD_PROCESS;
-#endif
   strncpy (ut.ut_line, line, sizeof ut.ut_line);
   strncpy (ut.ut_name, name, sizeof ut.ut_name);
-#if _HAVE_UT_HOST - 0
   strncpy (ut.ut_host, host, sizeof ut.ut_host);
-#endif
 
-#if _HAVE_UT_TV - 0
   struct timeval tv;
   __gettimeofday (&tv, NULL);
   ut.ut_tv.tv_sec = tv.tv_sec;
   ut.ut_tv.tv_usec = tv.tv_usec;
-#else
-  ut.ut_time = time (NULL);
-#endif
 
   updwtmp (_PATH_WTMP, &ut);
 }
index 4c312f0939626e7f3df81b1cc494101b65ff8d3d..85d8e31b43371d0ae7e653fe9bedd693d02a6c92 100644 (file)
@@ -37,47 +37,11 @@ print_entry (struct utmp *up)
   temp_tv.tv_sec = up->ut_tv.tv_sec;
   temp_tv.tv_usec = up->ut_tv.tv_usec;
 
-  (printf) (
-           /* The format string.  */
-#if _HAVE_UT_TYPE
-           "[%d] "
-#endif
-#if _HAVE_UT_PID
-           "[%05d] "
-#endif
-#if _HAVE_UT_ID
-           "[%-4.4s] "
-#endif
-           "[%-8.8s] [%-12.12s]"
-#if _HAVE_UT_HOST
-           " [%-16.16s]"
-#endif
-           " [%-15.15s]"
-#if _HAVE_UT_TV
-           " [%ld]"
-#endif
-           "\n"
-           /* The arguments.  */
-#if _HAVE_UT_TYPE
-           , up->ut_type
-#endif
-#if _HAVE_UT_PID
-           , up->ut_pid
-#endif
-#if _HAVE_UT_ID
-           , up->ut_id
-#endif
-           , up->ut_user, up->ut_line
-#if _HAVE_UT_HOST
-           , up->ut_host
-#endif
-#if _HAVE_UT_TV
-           , 4 + ctime (&temp_tv.tv_sec)
-           , (long int) temp_tv.tv_usec
-#else
-           , 4 + ctime (&up->ut_time)
-#endif
-          );
+  printf ("[%d] [%05d] [%-4.4s] [%-8.8s] [%-12.12s] [%-16.16s] [%-15.15s]"
+         " [%ld]\n",
+         up->ut_type, up->ut_pid, up->ut_id, up->ut_user, up->ut_line,
+         up->ut_host, 4 + ctime (&temp_tv.tv_sec),
+         (long int) temp_tv.tv_usec);
 }
 
 int
diff --git a/login/tst-pututxline-cache.c b/login/tst-pututxline-cache.c
new file mode 100644 (file)
index 0000000..3f30dd1
--- /dev/null
@@ -0,0 +1,193 @@
+/* Test case for cache invalidation after concurrent write (bug 24882).
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/* This test writes an entry to the utmpx file, reads it (so that it
+   is cached) in process1, and overwrites the same entry in process2
+   with something that does not match the search criteria.  At this
+   point, the cache of the first process is stale, and when process1
+   attempts to write a new record which would have gone to the same
+   place (as indicated by the cache), it needs to realize that it has
+   to pick a different slot because the old slot is now used for
+   something else.  */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/namespace.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/xthread.h>
+#include <support/xunistd.h>
+#include <utmp.h>
+#include <utmpx.h>
+
+/* Set to the path of the utmp file.  */
+static char *utmp_file;
+
+/* Used to synchronize the subprocesses.  The barrier itself is
+   allocated in shared memory.  */
+static pthread_barrier_t *barrier;
+
+/* setutxent with error checking.  */
+static void
+xsetutxent (void)
+{
+  errno = 0;
+  setutxent ();
+  TEST_COMPARE (errno, 0);
+}
+
+/* getutxent with error checking.  */
+static struct utmpx *
+xgetutxent (void)
+{
+  errno = 0;
+  struct utmpx *result = getutxent ();
+  if (result == NULL)
+    FAIL_EXIT1 ("getutxent: %m");
+  return result;
+}
+
+static void
+put_entry (const char *id, pid_t pid, const char *user, const char *line)
+{
+  struct utmpx ut =
+    {
+     .ut_type = LOGIN_PROCESS,
+     .ut_pid = pid,
+     .ut_host = "localhost",
+    };
+  strcpy (ut.ut_id, id);
+  strncpy (ut.ut_user, user, sizeof (ut.ut_user));
+  strncpy (ut.ut_line, line, sizeof (ut.ut_line));
+  TEST_VERIFY (pututxline (&ut) != NULL);
+}
+
+/* Use two cooperating subprocesses to avoid issues related to
+   unlock-on-close semantics of POSIX advisory locks.  */
+
+static __attribute__ ((noreturn)) void
+process1 (void)
+{
+  TEST_COMPARE (utmpname (utmp_file), 0);
+
+  /* Create an entry.  */
+  xsetutxent ();
+  put_entry ("1", 101, "root", "process1");
+
+  /* Retrieve the entry.  This will fill the internal cache.  */
+  {
+    errno = 0;
+    setutxent ();
+    TEST_COMPARE (errno, 0);
+    struct utmpx ut =
+      {
+       .ut_type = LOGIN_PROCESS,
+       .ut_line = "process1",
+      };
+    struct utmpx *result = getutxline (&ut);
+    if (result == NULL)
+      FAIL_EXIT1 ("getutxline (\"process1\"): %m");
+    TEST_COMPARE (result->ut_pid, 101);
+  }
+
+  /* Signal the other process to overwrite the entry.  */
+  xpthread_barrier_wait (barrier);
+
+  /* Wait for the other process to complete the write operation.  */
+  xpthread_barrier_wait (barrier);
+
+  /* Add another entry.  Note: This time, there is no setutxent call.  */
+  put_entry ("1", 103, "root", "process1");
+
+  _exit (0);
+}
+
+static void
+process2 (void *closure)
+{
+  /* Wait for the first process to write its entry.  */
+  xpthread_barrier_wait (barrier);
+
+  /* Truncate the file.  The glibc interface does not support
+     re-purposing records, but an external expiration mechanism may
+     trigger this.  */
+  TEST_COMPARE (truncate64 (utmp_file, 0), 0);
+
+  /* Write the replacement entry.  */
+  TEST_COMPARE (utmpname (utmp_file), 0);
+  xsetutxent ();
+  put_entry ("2", 102, "user", "process2");
+
+  /* Signal the other process that the entry has been replaced.  */
+  xpthread_barrier_wait (barrier);
+}
+
+static int
+do_test (void)
+{
+  xclose (create_temp_file ("tst-tumpx-cache-write-", &utmp_file));
+  {
+    pthread_barrierattr_t attr;
+    xpthread_barrierattr_init (&attr);
+    xpthread_barrierattr_setpshared (&attr, PTHREAD_SCOPE_PROCESS);
+    barrier = support_shared_allocate (sizeof (*barrier));
+    xpthread_barrier_init (barrier, &attr, 2);
+  }
+
+  /* Run both subprocesses in parallel.  */
+  {
+    pid_t pid1 = xfork ();
+    if (pid1 == 0)
+      process1 ();
+    support_isolate_in_subprocess (process2, NULL);
+    int status;
+    xwaitpid (pid1, &status, 0);
+    TEST_COMPARE (status, 0);
+  }
+
+  /* Check that the utmpx database contains the expected records.  */
+  {
+    TEST_COMPARE (utmpname (utmp_file), 0);
+    xsetutxent ();
+
+    struct utmpx *ut = xgetutxent ();
+    TEST_COMPARE_STRING (ut->ut_id, "2");
+    TEST_COMPARE (ut->ut_pid, 102);
+    TEST_COMPARE_STRING (ut->ut_user, "user");
+    TEST_COMPARE_STRING (ut->ut_line, "process2");
+
+    ut = xgetutxent ();
+    TEST_COMPARE_STRING (ut->ut_id, "1");
+    TEST_COMPARE (ut->ut_pid, 103);
+    TEST_COMPARE_STRING (ut->ut_user, "root");
+    TEST_COMPARE_STRING (ut->ut_line, "process1");
+
+    if (getutxent () != NULL)
+      FAIL_EXIT1 ("additional utmpx entry");
+  }
+
+  xpthread_barrier_destroy (barrier);
+  support_shared_free (barrier);
+  free (utmp_file);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/login/tst-pututxline-lockfail.c b/login/tst-pututxline-lockfail.c
new file mode 100644 (file)
index 0000000..47c25dc
--- /dev/null
@@ -0,0 +1,176 @@
+/* Test the lock upgrade path in tst-pututxline.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/* pututxline upgrades the read lock on the file to a write lock.
+   This test verifies that if the lock upgrade fails, the utmp
+   subsystem remains in a consistent state, so that pututxline can be
+   called again.  */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <support/check.h>
+#include <support/namespace.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/xthread.h>
+#include <support/xunistd.h>
+#include <unistd.h>
+#include <utmp.h>
+#include <utmpx.h>
+
+/* Path to the temporary utmp file.   */
+static char *path;
+
+/* Used to synchronize the subprocesses.  The barrier itself is
+   allocated in shared memory.  */
+static pthread_barrier_t *barrier;
+
+/* Use pututxline to write an entry for PID.  */
+static struct utmpx *
+write_entry (pid_t pid)
+{
+  struct utmpx ut =
+    {
+     .ut_type = LOGIN_PROCESS,
+     .ut_id = "1",
+     .ut_user = "root",
+     .ut_pid = pid,
+     .ut_line = "entry",
+     .ut_host = "localhost",
+    };
+  return pututxline (&ut);
+}
+
+/* Create the initial entry in a subprocess, so that the utmp
+   subsystem in the original process is not disturbed.  */
+static void
+subprocess_create_entry (void *closure)
+{
+  TEST_COMPARE (utmpname (path), 0);
+  TEST_VERIFY (write_entry (101) != NULL);
+}
+
+/* Acquire an advisory read lock on PATH.  */
+__attribute__ ((noreturn)) static void
+subprocess_lock_file (void)
+{
+  int fd = xopen (path, O_RDONLY, 0);
+
+  struct flock64 fl =
+    {
+     .l_type = F_RDLCK,
+     fl.l_whence = SEEK_SET,
+    };
+  TEST_COMPARE (fcntl64 (fd, F_SETLKW, &fl), 0);
+
+  /* Signal to the main process that the lock has been acquired.  */
+  xpthread_barrier_wait (barrier);
+
+  /* Wait for the unlock request from the main process.  */
+  xpthread_barrier_wait (barrier);
+
+  /* Implicitly unlock the file.  */
+  xclose (fd);
+
+  /* Overwrite the existing entry.  */
+  TEST_COMPARE (utmpname (path), 0);
+  errno = 0;
+  setutxent ();
+  TEST_COMPARE (errno, 0);
+  TEST_VERIFY (write_entry (102) != NULL);
+  errno = 0;
+  endutxent ();
+  TEST_COMPARE (errno, 0);
+
+  _exit (0);
+}
+
+static int
+do_test (void)
+{
+  xclose (create_temp_file ("tst-pututxline-lockfail-", &path));
+
+  {
+    pthread_barrierattr_t attr;
+    xpthread_barrierattr_init (&attr);
+    xpthread_barrierattr_setpshared (&attr, PTHREAD_SCOPE_PROCESS);
+    barrier = support_shared_allocate (sizeof (*barrier));
+    xpthread_barrier_init (barrier, &attr, 2);
+    xpthread_barrierattr_destroy (&attr);
+  }
+
+  /* Write the initial entry.  */
+  support_isolate_in_subprocess (subprocess_create_entry, NULL);
+
+  pid_t locker_pid = xfork ();
+  if (locker_pid == 0)
+    subprocess_lock_file ();
+
+  /* Wait for the file locking to complete.  */
+  xpthread_barrier_wait (barrier);
+
+  /* Try to add another entry.  This attempt will fail, with EINTR or
+     EAGAIN.  */
+  TEST_COMPARE (utmpname (path), 0);
+  TEST_VERIFY (write_entry (102) == NULL);
+  if (errno != EINTR)
+    TEST_COMPARE (errno, EAGAIN);
+
+  /* Signal the subprocess to overwrite the entry.  */
+  xpthread_barrier_wait (barrier);
+
+  /* Wait for write and unlock to complete.  */
+  {
+    int status;
+    xwaitpid (locker_pid, &status, 0);
+    TEST_COMPARE (status, 0);
+  }
+
+  /* The file is no longer locked, so this operation will succeed.  */
+  TEST_VERIFY (write_entry (103) != NULL);
+  errno = 0;
+  endutxent ();
+  TEST_COMPARE (errno, 0);
+
+  /* Check that there is just one entry with the expected contents.
+     If pututxline becomes desynchronized internally, the entry is not
+     overwritten (bug 24902).  */
+  errno = 0;
+  setutxent ();
+  TEST_COMPARE (errno, 0);
+  struct utmpx *ut = getutxent ();
+  TEST_VERIFY_EXIT (ut != NULL);
+  TEST_COMPARE (ut->ut_type, LOGIN_PROCESS);
+  TEST_COMPARE_STRING (ut->ut_id, "1");
+  TEST_COMPARE_STRING (ut->ut_user, "root");
+  TEST_COMPARE (ut->ut_pid, 103);
+  TEST_COMPARE_STRING (ut->ut_line, "entry");
+  TEST_COMPARE_STRING (ut->ut_host, "localhost");
+  TEST_VERIFY (getutxent () == NULL);
+  errno = 0;
+  endutxent ();
+  TEST_COMPARE (errno, 0);
+
+  xpthread_barrier_destroy (barrier);
+  support_shared_free (barrier);
+  free (path);
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/login/tst-updwtmpx.c b/login/tst-updwtmpx.c
new file mode 100644 (file)
index 0000000..0a4a27d
--- /dev/null
@@ -0,0 +1,112 @@
+/* Basic test coverage for updwtmpx.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/* This program runs a series of tests.  Each one calls updwtmpx
+   twice, to write two records, optionally with misalignment in the
+   file, and reads back the results.  */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <support/check.h>
+#include <support/descriptors.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/test-driver.h>
+#include <support/xunistd.h>
+#include <unistd.h>
+#include <utmpx.h>
+
+static int
+do_test (void)
+{
+  /* Two entries filled with an arbitrary bit pattern.  */
+  struct utmpx entries[2];
+  unsigned char pad;
+  {
+    unsigned char *p = (unsigned char *) &entries[0];
+    for (size_t i = 0; i < sizeof (entries); ++i)
+      {
+        p[i] = i;
+      }
+    /* Make sure that the first and second entry and the padding are
+       different.  */
+    p[sizeof (struct utmpx)] = p[0] + 1;
+    pad = p[0] + 2;
+  }
+
+  char *path;
+  int fd = create_temp_file ("tst-updwtmpx-", &path);
+
+  /* Used to check that updwtmpx does not leave an open file
+     descriptor around.  */
+  struct support_descriptors *descriptors = support_descriptors_list ();
+
+  /* updwtmpx is expected to remove misalignment.  Optionally insert
+     one byte of misalignment at the start and in the middle (after
+     the first entry).  */
+  for (int misaligned_start = 0; misaligned_start < 2; ++misaligned_start)
+    for (int misaligned_middle = 0; misaligned_middle < 2; ++misaligned_middle)
+      {
+        if (test_verbose > 0)
+          printf ("info: misaligned_start=%d misaligned_middle=%d\n",
+                  misaligned_start, misaligned_middle);
+
+        xftruncate (fd, 0);
+        TEST_COMPARE (pwrite64 (fd, &pad, misaligned_start, 0),
+                      misaligned_start);
+
+        /* Write first entry and check it.  */
+        errno = 0;
+        updwtmpx (path, &entries[0]);
+        TEST_COMPARE (errno, 0);
+        support_descriptors_check (descriptors);
+        TEST_COMPARE (xlseek (fd, 0, SEEK_END), sizeof (struct utmpx));
+        struct utmpx buffer;
+        TEST_COMPARE (pread64 (fd, &buffer, sizeof (buffer), 0),
+                      sizeof (buffer));
+        TEST_COMPARE_BLOB (&entries[0], sizeof (entries[0]),
+                           &buffer, sizeof (buffer));
+
+        /* Middle mis-alignmet.  */
+        TEST_COMPARE (pwrite64 (fd, &pad, misaligned_middle,
+                                sizeof (struct utmpx)), misaligned_middle);
+
+        /* Write second entry and check both entries.  */
+        errno = 0;
+        updwtmpx (path, &entries[1]);
+        TEST_COMPARE (errno, 0);
+        support_descriptors_check (descriptors);
+        TEST_COMPARE (xlseek (fd, 0, SEEK_END), 2 * sizeof (struct utmpx));
+        TEST_COMPARE (pread64 (fd, &buffer, sizeof (buffer), 0),
+                      sizeof (buffer));
+        TEST_COMPARE_BLOB (&entries[0], sizeof (entries[0]),
+                           &buffer, sizeof (buffer));
+        TEST_COMPARE (pread64 (fd, &buffer, sizeof (buffer), sizeof (buffer)),
+                      sizeof (buffer));
+        TEST_COMPARE_BLOB (&entries[1], sizeof (entries[1]),
+                           &buffer, sizeof (buffer));
+      }
+
+  support_descriptors_free (descriptors);
+  free (path);
+  xclose (fd);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
index ce48e8326ecc3a9c13a7e2b73ddc7c9aa8254424..02d0c1fe8c481c85633b3f4c161e30f2219c0095 100644 (file)
@@ -39,8 +39,6 @@
 #endif
 
 
-#if defined UTMPX || _HAVE_UT_TYPE
-
 /* Prototype for our test function.  */
 static int do_test (int argc, char *argv[]);
 
@@ -75,11 +73,7 @@ do_prepare (int argc, char *argv[])
 
 struct utmp entry[] =
 {
-#if defined UTMPX || _HAVE_UT_TV
 #define UT(a)  .ut_tv = { .tv_sec = (a)}
-#else
-#define UT(a)  .ut_time = (a)
-#endif
 
   { .ut_type = BOOT_TIME, .ut_pid = 1, UT(1000) },
   { .ut_type = RUN_LVL, .ut_pid = 1, UT(2000) },
@@ -167,11 +161,7 @@ simulate_login (const char *line, const char *user)
            entry[n].ut_pid = (entry_pid += 27);
          entry[n].ut_type = USER_PROCESS;
          strncpy (entry[n].ut_user, user, sizeof (entry[n].ut_user));
-#if defined UTMPX || _HAVE_UT_TV - 0
          entry[n].ut_tv.tv_sec = (entry_time += 1000);
-#else
-          entry[n].ut_time = (entry_time += 1000);
-#endif
          setutent ();
 
          if (pututline (&entry[n]) == NULL)
@@ -201,11 +191,7 @@ simulate_logout (const char *line)
        {
          entry[n].ut_type = DEAD_PROCESS;
          strncpy (entry[n].ut_user, "", sizeof (entry[n].ut_user));
-#if defined UTMPX || _HAVE_UT_TV - 0
           entry[n].ut_tv.tv_sec = (entry_time += 1000);
-#else
-          entry[n].ut_time = (entry_time += 1000);
-#endif
          setutent ();
 
          if (pututline (&entry[n]) == NULL)
@@ -390,14 +376,3 @@ do_test (int argc, char *argv[])
 
   return result;
 }
-
-#else
-
-/* No field 'ut_type' in struct utmp.  */
-int
-main (void)
-{
-  return 0;
-}
-
-#endif
index b9bccd9b678b985b92344cd66ec489b32f5f0187..387e5808284dd915180486c6e62bedb7f4537827 100644 (file)
@@ -29,7 +29,7 @@ __updwtmp (const char *wtmp_file, const struct utmp *utmp)
 {
   const char *file_name = TRANSFORM_UTMP_FILE_NAME (wtmp_file);
 
-  (*__libc_utmp_file_functions.updwtmp) (file_name, utmp);
+  __libc_updwtmp (file_name, utmp);
 }
 libc_hidden_def (__updwtmp)
 weak_alias (__updwtmp, updwtmp)
index a82a92365799ba29acfcdb94a6dfa388ca7ed106..d60461d6445ee278c05aae5f8185739f75311189 100644 (file)
 #include <utmp.h>
 #include <libc-lock.h>
 
-/* The structure describing the functions in a backend.  */
-struct utfuncs
-{
-  int (*setutent) (void);
-  int (*getutent_r) (struct utmp *, struct utmp **);
-  int (*getutid_r) (const struct utmp *, struct utmp *, struct utmp **);
-  int (*getutline_r) (const struct utmp *, struct utmp *, struct utmp **);
-  struct utmp *(*pututline) (const struct utmp *);
-  void (*endutent) (void);
-  int (*updwtmp) (const char *, const struct utmp *);
-};
-
-/* The tables from the services.  */
-extern const struct utfuncs __libc_utmp_file_functions attribute_hidden;
-extern const struct utfuncs __libc_utmp_unknown_functions attribute_hidden;
-
-/* Currently selected backend.  */
-extern const struct utfuncs *__libc_utmp_jump_table attribute_hidden;
+/* These functions check for initialization, but not perform any
+   locking.  */
+int __libc_setutent (void) attribute_hidden;
+int __libc_getutent_r (struct utmp *, struct utmp **) attribute_hidden;
+int __libc_getutid_r (const struct utmp *, struct utmp *, struct utmp **)
+  attribute_hidden;
+int __libc_getutline_r (const struct utmp *, struct utmp *, struct utmp **)
+  attribute_hidden;
+struct utmp *__libc_pututline (const struct utmp *) attribute_hidden;
+void __libc_endutent (void) attribute_hidden;
+int __libc_updwtmp (const char *, const struct utmp *) attribute_hidden;
 
 /* Current file name.  */
 extern const char *__libc_utmp_file_name attribute_hidden;
index b19d3caf0d8a028caa790d43ba8f54c964c5c8d5..e98bc318998e9b29f17c01948515c04ce1eb2ee1 100644 (file)
@@ -43,6 +43,25 @@ static off64_t file_offset;
 /* Cache for the last read entry.  */
 static struct utmp last_entry;
 
+/* Returns true if *ENTRY matches last_entry, based on
+   data->ut_type.  */
+static bool
+matches_last_entry (const struct utmp *data)
+{
+  if (file_offset <= 0)
+    /* Nothing has been read.  last_entry is stale and cannot match.  */
+    return false;
+
+  if (data->ut_type == RUN_LVL
+      || data->ut_type == BOOT_TIME
+      || data->ut_type == OLD_TIME
+      || data->ut_type == NEW_TIME)
+    /* For some entry types, only a type match is required.  */
+    return data->ut_type == last_entry.ut_type;
+  else
+    /* For the process-related entries, a full match is needed.  */
+    return __utmp_equal (&last_entry, data);
+}
 
 /* Locking timeout.  */
 #ifndef TIMEOUT
@@ -52,90 +71,70 @@ static struct utmp last_entry;
 /* Do-nothing handler for locking timeout.  */
 static void timeout_handler (int signum) {};
 
-/* LOCK_FILE(fd, type) failure_statement
-     attempts to get a lock on the utmp file referenced by FD.  If it fails,
-     the failure_statement is executed, otherwise it is skipped.
-   LOCKING_FAILED()
-     jumps into the UNLOCK_FILE macro and ensures cleanup of LOCK_FILE.
-   UNLOCK_FILE(fd)
-     unlocks the utmp file referenced by FD and performs the cleanup of
-     LOCK_FILE.
- */
-#define LOCK_FILE(fd, type) \
-{                                                                            \
-  struct flock fl;                                                           \
-  struct sigaction action, old_action;                                       \
-  unsigned int old_timeout;                                                  \
-                                                                             \
-  /* Cancel any existing alarm.  */                                          \
-  old_timeout = alarm (0);                                                   \
-                                                                             \
-  /* Establish signal handler.  */                                           \
-  action.sa_handler = timeout_handler;                                       \
-  __sigemptyset (&action.sa_mask);                                           \
-  action.sa_flags = 0;                                                       \
-  __sigaction (SIGALRM, &action, &old_action);                               \
-                                                                             \
-  alarm (TIMEOUT);                                                           \
-                                                                             \
-  /* Try to get the lock.  */                                                \
-  memset (&fl, '\0', sizeof (struct flock));                                 \
-  fl.l_type = (type);                                                        \
-  fl.l_whence = SEEK_SET;                                                    \
-  if (__fcntl64_nocancel ((fd), F_SETLKW, &fl) < 0)
-
-#define LOCKING_FAILED() \
-  goto unalarm_return
-
-#define UNLOCK_FILE(fd) \
-  /* Unlock the file.  */                                                    \
-  fl.l_type = F_UNLCK;                                                       \
-  __fcntl64_nocancel ((fd), F_SETLKW, &fl);                                  \
-                                                                             \
- unalarm_return:                                                             \
-  /* Reset the signal handler and alarm.  We must reset the alarm            \
-     before resetting the handler so our alarm does not generate a           \
-     spurious SIGALRM seen by the user.  However, we cannot just set         \
-     the user's old alarm before restoring the handler, because then         \
-     it's possible our handler could catch the user alarm's SIGARLM          \
-     and then the user would never see the signal he expected.  */           \
-  alarm (0);                                                                 \
-  __sigaction (SIGALRM, &old_action, NULL);                                  \
-  if (old_timeout != 0)                                                              \
-    alarm (old_timeout);                                                     \
-} while (0)
-
-
-/* Functions defined here.  */
-static int setutent_file (void);
-static int getutent_r_file (struct utmp *buffer, struct utmp **result);
-static int getutid_r_file (const struct utmp *key, struct utmp *buffer,
-                          struct utmp **result);
-static int getutline_r_file (const struct utmp *key, struct utmp *buffer,
-                            struct utmp **result);
-static struct utmp *pututline_file (const struct utmp *data);
-static void endutent_file (void);
-static int updwtmp_file (const char *file, const struct utmp *utmp);
-
-/* Jump table for file functions.  */
-const struct utfuncs __libc_utmp_file_functions =
+
+/* try_file_lock (LOCKING, FD, TYPE) returns true if the locking
+   operation failed and recovery needs to be performed.
+
+   file_unlock (FD) removes the lock (which must have been
+   successfully acquired). */
+
+static bool
+try_file_lock (int fd, int type)
 {
-  setutent_file,
-  getutent_r_file,
-  getutid_r_file,
-  getutline_r_file,
-  pututline_file,
-  endutent_file,
-  updwtmp_file
-};
+  /* Cancel any existing alarm.  */
+  int old_timeout = alarm (0);
+
+  /* Establish signal handler.  */
+  struct sigaction old_action;
+  struct sigaction action;
+  action.sa_handler = timeout_handler;
+  __sigemptyset (&action.sa_mask);
+  action.sa_flags = 0;
+  __sigaction (SIGALRM, &action, &old_action);
+
+  alarm (TIMEOUT);
+
+  /* Try to get the lock.  */
+ struct flock64 fl =
+   {
+    .l_type = type,
+    .l_whence = SEEK_SET,
+   };
+
+ bool status = __fcntl64_nocancel (fd, F_SETLKW, &fl) < 0;
+ int saved_errno = errno;
+
+ /* Reset the signal handler and alarm.  We must reset the alarm
+    before resetting the handler so our alarm does not generate a
+    spurious SIGALRM seen by the user.  However, we cannot just set
+    the user's old alarm before restoring the handler, because then
+    it's possible our handler could catch the user alarm's SIGARLM and
+    then the user would never see the signal he expected.  */
+  alarm (0);
+  __sigaction (SIGALRM, &old_action, NULL);
+  if (old_timeout != 0)
+    alarm (old_timeout);
+
+  __set_errno (saved_errno);
+  return status;
+}
 
+static void
+file_unlock (int fd)
+{
+  struct flock64 fl =
+    {
+      .l_type = F_UNLCK,
+    };
+  __fcntl64_nocancel (fd, F_SETLKW, &fl);
+}
 
 #ifndef TRANSFORM_UTMP_FILE_NAME
 # define TRANSFORM_UTMP_FILE_NAME(file_name) (file_name)
 #endif
 
-static int
-setutent_file (void)
+int
+__libc_setutent (void)
 {
   if (file_fd < 0)
     {
@@ -153,56 +152,68 @@ setutent_file (void)
   __lseek64 (file_fd, 0, SEEK_SET);
   file_offset = 0;
 
-  /* Make sure the entry won't match.  */
-#if _HAVE_UT_TYPE - 0
-  last_entry.ut_type = -1;
-#else
-  last_entry.ut_line[0] = '\177';
-# if _HAVE_UT_ID - 0
-  last_entry.ut_id[0] = '\0';
-# endif
-#endif
-
   return 1;
 }
 
+/* Preform initialization if necessary.  */
+static bool
+maybe_setutent (void)
+{
+  return file_fd >= 0 || __libc_setutent ();
+}
 
-static int
-getutent_r_file (struct utmp *buffer, struct utmp **result)
+/* Reads the entry at file_offset, storing it in last_entry and
+   updating file_offset on success.  Returns -1 for a read error, 0
+   for EOF, and 1 for a successful read.  last_entry and file_offset
+   are only updated on a successful and complete read.  */
+static ssize_t
+read_last_entry (void)
 {
-  ssize_t nbytes;
+  struct utmp buffer;
+  ssize_t nbytes = __pread64_nocancel (file_fd, &buffer, sizeof (buffer),
+                                      file_offset);
+  if (nbytes < 0)
+    return -1;
+  else if (nbytes != sizeof (buffer))
+    /* Assume EOF.  */
+    return 0;
+  else
+    {
+      last_entry = buffer;
+      file_offset += sizeof (buffer);
+      return 1;
+    }
+}
 
-  assert (file_fd >= 0);
+int
+__libc_getutent_r (struct utmp *buffer, struct utmp **result)
+{
+  int saved_errno = errno;
 
-  if (file_offset == -1l)
+  if (!maybe_setutent ())
     {
       /* Not available.  */
       *result = NULL;
       return -1;
     }
 
-  LOCK_FILE (file_fd, F_RDLCK)
-    {
-      nbytes = 0;
-      LOCKING_FAILED ();
-    }
-
-  /* Read the next entry.  */
-  nbytes = __read_nocancel (file_fd, &last_entry, sizeof (struct utmp));
+  if (try_file_lock (file_fd, F_RDLCK))
+    return -1;
 
-  UNLOCK_FILE (file_fd);
+  ssize_t nbytes = read_last_entry ();
+  file_unlock (file_fd);
 
-  if (nbytes != sizeof (struct utmp))
+  if (nbytes <= 0)             /* Read error or EOF.  */
     {
-      if (nbytes != 0)
-       file_offset = -1l;
+      if (nbytes == 0)
+       /* errno should be unchanged to indicate success.  A premature
+          EOF is treated like an EOF (missing complete record at the
+          end).  */
+       __set_errno (saved_errno);
       *result = NULL;
       return -1;
     }
 
-  /* Update position pointer.  */
-  file_offset += sizeof (struct utmp);
-
   memcpy (buffer, &last_entry, sizeof (struct utmp));
   *result = buffer;
 
@@ -210,82 +221,55 @@ getutent_r_file (struct utmp *buffer, struct utmp **result)
 }
 
 
+/* Search for *ID, updating last_entry and file_offset.  Return 0 on
+   success and -1 on failure.  Does not perform locking; for that see
+   internal_getut_r below.  */
 static int
-internal_getut_r (const struct utmp *id, struct utmp *buffer,
-                 bool *lock_failed)
+internal_getut_nolock (const struct utmp *id)
 {
-  int result = -1;
-
-  LOCK_FILE (file_fd, F_RDLCK)
-    {
-      *lock_failed = true;
-      LOCKING_FAILED ();
-    }
-
-#if _HAVE_UT_TYPE - 0
-  if (id->ut_type == RUN_LVL || id->ut_type == BOOT_TIME
-      || id->ut_type == OLD_TIME || id->ut_type == NEW_TIME)
+  while (1)
     {
-      /* Search for next entry with type RUN_LVL, BOOT_TIME,
-        OLD_TIME, or NEW_TIME.  */
-
-      while (1)
+      ssize_t nbytes = read_last_entry ();
+      if (nbytes < 0)
+       return -1;
+      if (nbytes == 0)
        {
-         /* Read the next entry.  */
-         if (__read_nocancel (file_fd, buffer, sizeof (struct utmp))
-             != sizeof (struct utmp))
-           {
-             __set_errno (ESRCH);
-             file_offset = -1l;
-             goto unlock_return;
-           }
-         file_offset += sizeof (struct utmp);
-
-         if (id->ut_type == buffer->ut_type)
-           break;
+         /* End of file reached.  */
+         __set_errno (ESRCH);
+         return -1;
        }
-    }
-  else
-#endif /* _HAVE_UT_TYPE */
-    {
-      /* Search for the next entry with the specified ID and with type
-        INIT_PROCESS, LOGIN_PROCESS, USER_PROCESS, or DEAD_PROCESS.  */
 
-      while (1)
-       {
-         /* Read the next entry.  */
-         if (__read_nocancel (file_fd, buffer, sizeof (struct utmp))
-             != sizeof (struct utmp))
-           {
-             __set_errno (ESRCH);
-             file_offset = -1l;
-             goto unlock_return;
-           }
-         file_offset += sizeof (struct utmp);
-
-         if (__utmp_equal (buffer, id))
-           break;
-       }
+      if (matches_last_entry (id))
+       break;
     }
 
-  result = 0;
+  return 0;
+}
 
-unlock_return:
-  UNLOCK_FILE (file_fd);
+/* Search for *ID, updating last_entry and file_offset.  Return 0 on
+   success and -1 on failure.  If the locking operation failed, write
+   true to *LOCK_FAILED.  */
+static int
+internal_getut_r (const struct utmp *id, bool *lock_failed)
+{
+  if (try_file_lock (file_fd, F_RDLCK))
+    {
+      *lock_failed = true;
+      return -1;
+    }
 
+  int result = internal_getut_nolock (id);
+  file_unlock (file_fd);
   return result;
 }
 
-
 /* For implementing this function we don't use the getutent_r function
    because we can avoid the reposition on every new entry this way.  */
-static int
-getutid_r_file (const struct utmp *id, struct utmp *buffer,
-               struct utmp **result)
+int
+__libc_getutid_r (const struct utmp *id, struct utmp *buffer,
+                 struct utmp **result)
 {
-  assert (file_fd >= 0);
-
-  if (file_offset == -1l)
+  if (!maybe_setutent ())
     {
       *result = NULL;
       return -1;
@@ -294,7 +278,7 @@ getutid_r_file (const struct utmp *id, struct utmp *buffer,
   /* We don't have to distinguish whether we can lock the file or
      whether there is no entry.  */
   bool lock_failed = false;
-  if (internal_getut_r (id, &last_entry, &lock_failed) < 0)
+  if (internal_getut_r (id, &lock_failed) < 0)
     {
       *result = NULL;
       return -1;
@@ -306,69 +290,65 @@ getutid_r_file (const struct utmp *id, struct utmp *buffer,
   return 0;
 }
 
-
 /* For implementing this function we don't use the getutent_r function
    because we can avoid the reposition on every new entry this way.  */
-static int
-getutline_r_file (const struct utmp *line, struct utmp *buffer,
-                 struct utmp **result)
+int
+__libc_getutline_r (const struct utmp *line, struct utmp *buffer,
+                   struct utmp **result)
 {
-  assert (file_fd >= 0);
-
-  if (file_offset == -1l)
+  if (!maybe_setutent ())
     {
       *result = NULL;
       return -1;
     }
 
-  LOCK_FILE (file_fd, F_RDLCK)
+  if (try_file_lock (file_fd, F_RDLCK))
     {
       *result = NULL;
-      LOCKING_FAILED ();
+      return -1;
     }
 
   while (1)
     {
-      /* Read the next entry.  */
-      if (__read_nocancel (file_fd, &last_entry, sizeof (struct utmp))
-         != sizeof (struct utmp))
+      ssize_t nbytes = read_last_entry ();
+      if (nbytes < 0)
+       {
+         file_unlock (file_fd);
+         *result = NULL;
+         return -1;
+       }
+      if (nbytes == 0)
        {
+         /* End of file reached.  */
+         file_unlock (file_fd);
          __set_errno (ESRCH);
-         file_offset = -1l;
          *result = NULL;
-         goto unlock_return;
+         return -1;
        }
-      file_offset += sizeof (struct utmp);
 
       /* Stop if we found a user or login entry.  */
-      if (
-#if _HAVE_UT_TYPE - 0
-         (last_entry.ut_type == USER_PROCESS
+      if ((last_entry.ut_type == USER_PROCESS
           || last_entry.ut_type == LOGIN_PROCESS)
-         &&
-#endif
-         !strncmp (line->ut_line, last_entry.ut_line, sizeof line->ut_line))
+         && (strncmp (line->ut_line, last_entry.ut_line, sizeof line->ut_line)
+             == 0))
        break;
     }
 
+  file_unlock (file_fd);
   memcpy (buffer, &last_entry, sizeof (struct utmp));
   *result = buffer;
 
-unlock_return:
-  UNLOCK_FILE (file_fd);
-
-  return ((*result == NULL) ? -1 : 0);
+  return 0;
 }
 
 
-static struct utmp *
-pututline_file (const struct utmp *data)
+struct utmp *
+__libc_pututline (const struct utmp *data)
 {
-  struct utmp buffer;
-  struct utmp *pbuf;
-  int found;
+  if (!maybe_setutent ())
+    return NULL;
 
-  assert (file_fd >= 0);
+  struct utmp *pbuf;
 
   if (! file_writable)
     {
@@ -380,8 +360,7 @@ pututline_file (const struct utmp *data)
       if (new_fd == -1)
        return NULL;
 
-      if (__lseek64 (new_fd, __lseek64 (file_fd, 0, SEEK_CUR), SEEK_SET) == -1
-         || __dup2 (new_fd, file_fd) < 0)
+      if (__dup2 (new_fd, file_fd) < 0)
        {
          __close_nocancel_nostatus (new_fd);
          return NULL;
@@ -390,95 +369,96 @@ pututline_file (const struct utmp *data)
       file_writable = true;
     }
 
+  /* Exclude other writers before validating the cache.  */
+  if (try_file_lock (file_fd, F_WRLCK))
+    return NULL;
+
   /* Find the correct place to insert the data.  */
-  if (file_offset > 0
-      && (
-#if _HAVE_UT_TYPE - 0
-         (last_entry.ut_type == data->ut_type
-          && (last_entry.ut_type == RUN_LVL
-              || last_entry.ut_type == BOOT_TIME
-              || last_entry.ut_type == OLD_TIME
-              || last_entry.ut_type == NEW_TIME))
-         ||
-#endif
-         __utmp_equal (&last_entry, data)))
-    found = 1;
-  else
+  bool found = false;
+  if (matches_last_entry (data))
     {
-      bool lock_failed = false;
-      found = internal_getut_r (data, &buffer, &lock_failed);
-
-      if (__builtin_expect (lock_failed, false))
+      /* Read back the entry under the write lock.  */
+      file_offset -= sizeof (last_entry);
+      ssize_t nbytes = read_last_entry ();
+      if (nbytes < 0)
        {
-         __set_errno (EAGAIN);
+         file_unlock (file_fd);
          return NULL;
        }
-    }
 
-  LOCK_FILE (file_fd, F_WRLCK)
-    {
-      pbuf = NULL;
-      LOCKING_FAILED ();
+      if (nbytes == 0)
+       /* End of file reached.  */
+       found = false;
+      else
+       found = matches_last_entry (data);
     }
 
-  if (found < 0)
+  if (!found)
+    /* Search forward for the entry.  */
+    found = internal_getut_nolock (data) >= 0;
+
+  off64_t write_offset;
+  if (!found)
     {
       /* We append the next entry.  */
-      file_offset = __lseek64 (file_fd, 0, SEEK_END);
-      if (file_offset % sizeof (struct utmp) != 0)
-       {
-         file_offset -= file_offset % sizeof (struct utmp);
-         __ftruncate64 (file_fd, file_offset);
-
-         if (__lseek64 (file_fd, 0, SEEK_END) < 0)
-           {
-             pbuf = NULL;
-             goto unlock_return;
-           }
-       }
+      write_offset = __lseek64 (file_fd, 0, SEEK_END);
+
+      /* Round down to the next multiple of the entry size.  This
+        ensures any partially-written record is overwritten by the
+        new record.  */
+      write_offset = (write_offset / sizeof (struct utmp)
+                     * sizeof (struct utmp));
     }
   else
+    /* Overwrite last_entry.  */
+    write_offset = file_offset - sizeof (struct utmp);
+
+  /* Write the new data.  */
+  ssize_t nbytes;
+  if (__lseek64 (file_fd, write_offset, SEEK_SET) < 0
+      || (nbytes = __write_nocancel (file_fd, data, sizeof (struct utmp))) < 0)
     {
-      /* We replace the just read entry.  */
-      file_offset -= sizeof (struct utmp);
-      __lseek64 (file_fd, file_offset, SEEK_SET);
+      /* There is no need to recover the file position because all
+        reads use pread64, and any future write is preceded by
+        another seek.  */
+      file_unlock (file_fd);
+      return NULL;
     }
 
-  /* Write the new data.  */
-  if (__write_nocancel (file_fd, data, sizeof (struct utmp))
-      != sizeof (struct utmp))
+  if (nbytes != sizeof (struct utmp))
     {
       /* If we appended a new record this is only partially written.
         Remove it.  */
-      if (found < 0)
-       (void) __ftruncate64 (file_fd, file_offset);
-      pbuf = NULL;
-    }
-  else
-    {
-      file_offset += sizeof (struct utmp);
-      pbuf = (struct utmp *) data;
+      if (!found)
+       (void) __ftruncate64 (file_fd, write_offset);
+      file_unlock (file_fd);
+      /* Assume that the write failure was due to missing disk
+        space.  */
+      __set_errno (ENOSPC);
+      return NULL;
     }
 
- unlock_return:
-  UNLOCK_FILE (file_fd);
+  file_unlock (file_fd);
+  file_offset = write_offset + sizeof (struct utmp);
+  pbuf = (struct utmp *) data;
 
   return pbuf;
 }
 
 
-static void
-endutent_file (void)
+void
+__libc_endutent (void)
 {
-  assert (file_fd >= 0);
-
-  __close_nocancel_nostatus (file_fd);
-  file_fd = -1;
+  if (file_fd >= 0)
+    {
+      __close_nocancel_nostatus (file_fd);
+      file_fd = -1;
+    }
 }
 
 
-static int
-updwtmp_file (const char *file, const struct utmp *utmp)
+int
+__libc_updwtmp (const char *file, const struct utmp *utmp)
 {
   int result = -1;
   off64_t offset;
@@ -489,8 +469,11 @@ updwtmp_file (const char *file, const struct utmp *utmp)
   if (fd < 0)
     return -1;
 
-  LOCK_FILE (fd, F_WRLCK)
-    LOCKING_FAILED ();
+  if (try_file_lock (fd, F_WRLCK))
+    {
+      __close_nocancel_nostatus (fd);
+      return -1;
+    }
 
   /* Remember original size of log file.  */
   offset = __lseek64 (fd, 0, SEEK_END);
@@ -516,7 +499,7 @@ updwtmp_file (const char *file, const struct utmp *utmp)
   result = 0;
 
 unlock_return:
-  UNLOCK_FILE (fd);
+  file_unlock (fd);
 
   /* Close WTMP file.  */
   __close_nocancel_nostatus (fd);
index c3da183d5bbcdeb83283a90570227942d160e58d..8f94b19cafc9c0824a166414324c6ad25e571b6f 100644 (file)
@@ -42,8 +42,7 @@ __utmpname (const char *file)
   __libc_lock_lock (__libc_utmp_lock);
 
   /* Close the old file.  */
-  (*__libc_utmp_jump_table->endutent) ();
-  __libc_utmp_jump_table = &__libc_utmp_unknown_functions;
+  __libc_endutent ();
 
   if (strcmp (file, __libc_utmp_file_name) != 0)
     {
index d2fba29953c1773720918c6f0ee565054f1a8e4b..9698574bba267cbae7e57af6b23bbbcd2d69fa66 100644 (file)
@@ -27,7 +27,7 @@ headers := $(dist-headers) obstack.h mcheck.h
 tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
         tst-mcheck tst-mallocfork tst-trim1 \
         tst-malloc-usable tst-realloc tst-reallocarray tst-posix_memalign \
-        tst-pvalloc tst-memalign tst-mallopt \
+        tst-pvalloc tst-pvalloc-fortify tst-memalign tst-mallopt \
         tst-malloc-backtrace tst-malloc-thread-exit \
         tst-malloc-thread-fail tst-malloc-fork-deadlock \
         tst-mallocfork2 \
@@ -54,7 +54,7 @@ tests-internal += \
         tst-dynarray-at-fail \
 
 ifneq (no,$(have-tunables))
-tests += tst-malloc-usable-tunables
+tests += tst-malloc-usable-tunables tst-mxfast
 tests-static += tst-malloc-usable-static-tunables
 endif
 
@@ -196,6 +196,8 @@ tst-malloc-usable-static-ENV = $(tst-malloc-usable-ENV)
 tst-malloc-usable-tunables-ENV = GLIBC_TUNABLES=glibc.malloc.check=3
 tst-malloc-usable-static-tunables-ENV = $(tst-malloc-usable-tunables-ENV)
 
+tst-mxfast-ENV = GLIBC_TUNABLES=glibc.malloc.tcache_count=0:glibc.malloc.mxfast=0
+
 ifeq ($(experimental-malloc),yes)
 CPPFLAGS-malloc.c += -DUSE_TCACHE=1
 else
index 8309c1334cb1bab2ef230960fe60b34f66d844c9..a32eb403ec33580797254fbae44d7f9f7ef84790 100644 (file)
@@ -236,6 +236,7 @@ TUNABLE_CALLBACK_FNDECL (set_tcache_max, size_t)
 TUNABLE_CALLBACK_FNDECL (set_tcache_count, size_t)
 TUNABLE_CALLBACK_FNDECL (set_tcache_unsorted_limit, size_t)
 #endif
+TUNABLE_CALLBACK_FNDECL (set_mxfast, size_t)
 #else
 /* Initialization routine. */
 #include <string.h>
@@ -323,6 +324,7 @@ ptmalloc_init (void)
   TUNABLE_GET (tcache_unsorted_limit, size_t,
               TUNABLE_CALLBACK (set_tcache_unsorted_limit));
 # endif
+  TUNABLE_GET (mxfast, size_t, TUNABLE_CALLBACK (set_mxfast));
 #else
   const char *s = NULL;
   if (__glibc_likely (_environ != NULL))
index 00ce48cf5879c87f051af781e9b2d99f384e55dd..8c68b21b2be16a088b0cf669fd1441ff98e4f178 100644 (file)
@@ -1621,7 +1621,7 @@ static INTERNAL_SIZE_T global_max_fast;
 
 #define set_max_fast(s) \
   global_max_fast = (((s) == 0)                                                      \
-                     ? SMALLBIN_WIDTH : ((s + SIZE_SZ) & ~MALLOC_ALIGN_MASK))
+                     ? MIN_CHUNK_SIZE / 2 : ((s + SIZE_SZ) & ~MALLOC_ALIGN_MASK))
 
 static inline INTERNAL_SIZE_T
 get_max_fast (void)
@@ -5115,6 +5115,19 @@ do_set_tcache_unsorted_limit (size_t value)
 }
 #endif
 
+static inline int
+__always_inline
+do_set_mxfast (size_t value)
+{
+  if (value >= 0 && value <= MAX_FAST_SIZE)
+    {
+      LIBC_PROBE (memory_mallopt_mxfast, 2, value, get_max_fast ());
+      set_max_fast (value);
+      return 1;
+    }
+  return 0;
+}
+
 int
 __libc_mallopt (int param_number, int value)
 {
@@ -5134,13 +5147,7 @@ __libc_mallopt (int param_number, int value)
   switch (param_number)
     {
     case M_MXFAST:
-      if (value >= 0 && value <= MAX_FAST_SIZE)
-        {
-          LIBC_PROBE (memory_mallopt_mxfast, 2, value, get_max_fast ());
-          set_max_fast (value);
-        }
-      else
-        res = 0;
+      do_set_mxfast (value);
       break;
 
     case M_TRIM_THRESHOLD:
@@ -5406,6 +5413,12 @@ __malloc_info (int options, FILE *fp)
 
       __libc_lock_lock (ar_ptr->mutex);
 
+      /* Account for top chunk.  The top-most available chunk is
+        treated specially and is never in any bin. See "initial_top"
+        comments.  */
+      avail = chunksize (ar_ptr->top);
+      nblocks = 1;  /* Top always exists.  */
+
       for (size_t i = 0; i < NFASTBINS; ++i)
        {
          mchunkptr p = fastbin (ar_ptr, i);
@@ -5491,7 +5504,7 @@ __malloc_info (int options, FILE *fp)
 
       for (size_t i = 0; i < nsizes; ++i)
        if (sizes[i].count != 0 && i != NFASTBINS)
-         fprintf (fp, "                                                              \
+         fprintf (fp, "\
   <size from=\"%zu\" to=\"%zu\" total=\"%zu\" count=\"%zu\"/>\n",
                   sizes[i].from, sizes[i].to, sizes[i].total, sizes[i].count);
 
index 70d8282bdccb32868794e814fcbc68decff98f32..f62c6c594c481ce945fed75852ef57c6b7546f85 100644 (file)
@@ -71,8 +71,7 @@ extern void *valloc (size_t __size) __THROW __attribute_malloc__
 
 /* Equivalent to valloc(minimum-page-that-holds(n)), that is, round up
    __size to nearest pagesize. */
-extern void *pvalloc (size_t __size) __THROW __attribute_malloc__
-     __attribute_alloc_size__ ((1)) __wur;
+extern void *pvalloc (size_t __size) __THROW __attribute_malloc__ __wur;
 
 /* Underlying allocation function; successive calls should return
    contiguous pieces of memory.  */
index 30e7abe6fda70244fabedaa4ced206a697d994bb..c21e4d779aa8aff54acac32e4319c26c0eaab148 100644 (file)
@@ -62,6 +62,9 @@ static volatile sig_atomic_t sigusr1_received;
    progress.  Checked by liveness_signal_handler.  */
 static volatile sig_atomic_t progress_indicator = 1;
 
+/* Set to 1 if an error occurs in the signal handler.  */
+static volatile sig_atomic_t error_indicator = 0;
+
 static void
 sigusr1_handler (int signo)
 {
@@ -72,7 +75,8 @@ sigusr1_handler (int signo)
   if (pid == -1)
     {
       write_message ("error: fork\n");
-      abort ();
+      error_indicator = 1;
+      return;
     }
   if (pid == 0)
     _exit (0);
@@ -81,12 +85,14 @@ sigusr1_handler (int signo)
   if (ret < 0)
     {
       write_message ("error: waitpid\n");
-      abort ();
+      error_indicator = 1;
+      return;
     }
   if (status != 0)
     {
       write_message ("error: unexpected exit status from subprocess\n");
-      abort ();
+      error_indicator = 1;
+      return;
     }
 }
 
@@ -122,9 +128,25 @@ signal_sender (int signo, bool sleep)
     }
 }
 
+/* Children processes.  */
+static pid_t sigusr1_sender_pids[5] = { 0 };
+static pid_t sigusr2_sender_pid = 0;
+
+static void
+kill_children (void)
+{
+  for (size_t i = 0; i < array_length (sigusr1_sender_pids); ++i)
+    if (sigusr1_sender_pids[i] > 0)
+      kill (sigusr1_sender_pids[i], SIGKILL);
+  if (sigusr2_sender_pid > 0)
+    kill (sigusr2_sender_pid, SIGKILL);
+}
+
 static int
 do_test (void)
 {
+  atexit (kill_children);
+
   /* shared->barrier is intialized along with sigusr1_sender_pids
      below.  */
   shared = support_shared_allocate (sizeof (*shared));
@@ -148,14 +170,13 @@ do_test (void)
       return 1;
     }
 
-  pid_t sigusr2_sender_pid = xfork ();
+  sigusr2_sender_pid = xfork ();
   if (sigusr2_sender_pid == 0)
     signal_sender (SIGUSR2, true);
 
   /* Send SIGUSR1 signals from several processes.  Hopefully, one
      signal will hit one of the ciritical functions.  Use a barrier to
      avoid sending signals while not running fork/free/malloc.  */
-  pid_t sigusr1_sender_pids[5];
   {
     pthread_barrierattr_t attr;
     xpthread_barrierattr_init (&attr);
@@ -166,7 +187,7 @@ do_test (void)
   }
   for (size_t i = 0; i < array_length (sigusr1_sender_pids); ++i)
     {
-      sigusr1_sender_pids[i] = fork ();
+      sigusr1_sender_pids[i] = xfork ();
       if (sigusr1_sender_pids[i] == 0)
         signal_sender (SIGUSR1, false);
     }
@@ -211,7 +232,7 @@ do_test (void)
         ++malloc_signals;
       xpthread_barrier_wait (&shared->barrier);
 
-      if (objects[slot] == NULL)
+      if (objects[slot] == NULL || error_indicator != 0)
         {
           printf ("error: malloc: %m\n");
           for (size_t i = 0; i < array_length (sigusr1_sender_pids); ++i)
@@ -225,10 +246,6 @@ do_test (void)
   for (int slot = 0; slot < malloc_objects; ++slot)
     free (objects[slot]);
 
-  for (size_t i = 0; i < array_length (sigusr1_sender_pids); ++i)
-    kill (sigusr1_sender_pids[i], SIGKILL);
-  kill (sigusr2_sender_pid, SIGKILL);
-
   printf ("info: signals received during fork: %u\n", fork_signals);
   printf ("info: signals received during free: %u\n", free_signals);
   printf ("info: signals received during malloc: %u\n", malloc_signals);
diff --git a/malloc/tst-mxfast.c b/malloc/tst-mxfast.c
new file mode 100644 (file)
index 0000000..7a7750b
--- /dev/null
@@ -0,0 +1,50 @@
+/* Test that glibc.malloc.mxfast tunable works.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* This test verifies that setting the glibc.malloc.mxfast tunable to
+   zero results in free'd blocks being returned to the small bins, not
+   the fast bins.  */
+
+#include <malloc.h>
+#include <support/check.h>
+
+int
+do_test (void)
+{
+  struct mallinfo m;
+  char *volatile p1;
+  char *volatile p2;
+
+  /* Arbitrary value; must be in default fastbin range.  */
+  p1 = malloc (3);
+  /* Something large so that p1 isn't a "top block" */
+  p2 = malloc (512);
+  free (p1);
+
+  m = mallinfo ();
+
+  /* This will fail if there are any blocks in the fastbins.  */
+  TEST_COMPARE (m.smblks, 0);
+
+  /* To keep gcc happy.  */
+  free (p2);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/malloc/tst-pvalloc-fortify.c b/malloc/tst-pvalloc-fortify.c
new file mode 100644 (file)
index 0000000..391b7fa
--- /dev/null
@@ -0,0 +1,48 @@
+/* Test fortify-source allocation size handling in pvalloc (bug 25401).
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, see <https://www.gnu.org/licenses/>.  */
+
+#undef _FORTIFY_SOURCE
+#define _FORTIFY_SOURCE 2
+#include <malloc.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/xunistd.h>
+#include <unistd.h>
+
+static int
+do_test (void)
+{
+  /* The test below assumes that pvalloc rounds up the allocation size
+     to at least 8.  */
+  TEST_VERIFY (xsysconf (_SC_PAGESIZE) >= 8);
+
+  void *p = pvalloc (5);
+  TEST_VERIFY_EXIT (p != NULL);
+
+  /* This is valid assuming the page size is at least 8 because
+     pvalloc rounds up the allocation size to a multiple of the page
+     size.  Due to bug 25041, this used to trigger a compiler
+     warning.  */
+  strcpy (p, "abcdefg");
+
+  asm ("" : : "g" (p) : "memory"); /* Optimization barrier.  */
+  TEST_VERIFY (malloc_usable_size (p) >= xsysconf (_SC_PAGESIZE));
+  return 0;
+}
+
+#include <support/test-driver.c>
index f1bd994a104c52442a20b6db90add12637e915d8..b1695376dc07872ccbb8d7dfec2e5c2975187f62 100644 (file)
 # define __glibc_has_attribute(attr)   0
 #endif
 
-#ifdef __has_include
-/* Do not use a function-like macro, so that __has_include can inhibit
-   macro expansion.  */
-# define __glibc_has_include __has_include
-#else
-# define __glibc_has_include(header)   0
-#endif
-
 #if (!defined _Noreturn \
      && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
      &&  !__GNUC_PREREQ (4,7))
index e73e35c510cc1e1f7523ee6556db06920fc2e002..c6cbd0eb4375f417a14509dba0085d59d0361fa2 100644 (file)
@@ -827,31 +827,32 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
              {
                size_t home_len = strlen (p->pw_dir);
                size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
-               char *d;
+               char *d, *newp;
+               bool use_alloca = glob_use_alloca (alloca_used,
+                                                  home_len + rest_len + 1);
 
-               if (__glibc_unlikely (malloc_dirname))
-                 free (dirname);
-               malloc_dirname = 0;
-
-               if (glob_use_alloca (alloca_used, home_len + rest_len + 1))
-                 dirname = alloca_account (home_len + rest_len + 1,
-                                           alloca_used);
+               if (use_alloca)
+                 newp = alloca_account (home_len + rest_len + 1, alloca_used);
                else
                  {
-                   dirname = malloc (home_len + rest_len + 1);
-                   if (dirname == NULL)
+                   newp = malloc (home_len + rest_len + 1);
+                   if (newp == NULL)
                      {
                        scratch_buffer_free (&pwtmpbuf);
                        retval = GLOB_NOSPACE;
                        goto out;
                      }
-                   malloc_dirname = 1;
                  }
-               d = mempcpy (dirname, p->pw_dir, home_len);
+               d = mempcpy (newp, p->pw_dir, home_len);
                if (end_name != NULL)
                  d = mempcpy (d, end_name, rest_len);
                *d = '\0';
 
+               if (__glibc_unlikely (malloc_dirname))
+                 free (dirname);
+               dirname = newp;
+               malloc_dirname = !use_alloca;
+
                dirlen = home_len + rest_len;
                dirname_modified = 1;
              }
index 32f6050ecccd0793b92151607e65d2f7094bb0a6..4b2bdb08af49027cc12dec99bd7b0c3a4322200b 100644 (file)
@@ -70,7 +70,7 @@ tests         := tst-strtol tst-strtod testmb testrand testsort testdiv   \
                   test-canon test-canon2 tst-strtoll tst-environ           \
                   tst-xpg-basename tst-random tst-random2 tst-bsearch      \
                   tst-limits tst-rand48 bug-strtod tst-setcontext          \
-                  tst-setcontext2 test-a64l tst-qsort tst-system testmb2   \
+                  tst-setcontext2 test-a64l tst-qsort testmb2              \
                   bug-strtod2 tst-atof1 tst-atof2 tst-strtod2              \
                   tst-rand48-2 tst-makecontext tst-strtod5                 \
                   tst-qsort2 tst-makecontext2 tst-strtod6 tst-unsetenv1    \
@@ -92,6 +92,7 @@ tests         := tst-strtol tst-strtod testmb testrand testsort testdiv   \
 tests-internal := tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
                   tst-tls-atexit tst-tls-atexit-nodelete
 tests-static   := tst-secure-getenv
+tests-container := tst-system
 
 ifeq ($(build-hardcoded-path-in-tests),yes)
 tests += tst-empty-env
index 06afbf24c7c27b7d1b091c5f91a68da90da3b19b..8e1f23d5c9749622580ce1e1922fb97a6b262efe 100644 (file)
    <http://www.gnu.org/licenses/>.  */
 
 #include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <paths.h>
 
+#include <support/capture_subprocess.h>
+#include <support/check.h>
+#include <support/temp_file.h>
+#include <support/support.h>
+
+static char *tmpdir;
+static long int namemax;
+
+static void
+do_prepare (int argc, char *argv[])
+{
+  tmpdir = support_create_temp_directory ("tst-system-");
+  /* Include the last '/0'.  */
+  namemax = pathconf (tmpdir, _PC_NAME_MAX) + 1;
+  TEST_VERIFY_EXIT (namemax != -1);
+}
+#define PREPARE do_prepare
+
+struct args
+{
+  const char *command;
+  int exit_status;
+  int term_sig;
+  const char *path;
+};
+
+static void
+call_system (void *closure)
+{
+  struct args *args = (struct args *) closure;
+  int ret;
+
+  if (args->path != NULL)
+    TEST_COMPARE (setenv ("PATH", args->path, 1), 0);
+  ret = system (args->command);
+  if (args->term_sig == 0)
+    {
+      /* Expect regular termination.  */
+      TEST_VERIFY (WIFEXITED (ret) != 0);
+      TEST_COMPARE (WEXITSTATUS (ret), args->exit_status);
+    }
+  else
+    {
+      /* status_or_signal < 0.  Expect termination by signal.  */
+      TEST_VERIFY (WIFSIGNALED (ret) != 0);
+      TEST_COMPARE (WTERMSIG (ret), args->term_sig);
+    }
+}
 
 static int
 do_test (void)
 {
-  return system (":");
-}
+  TEST_VERIFY (system (NULL) != 0);
 
+  {
+    char cmd[namemax];
+    memset (cmd, 'a', sizeof(cmd));
+    cmd[sizeof(cmd) - 1] = '\0';
+
+    struct support_capture_subprocess result;
+    result = support_capture_subprocess (call_system,
+                                        &(struct args) {
+                                          cmd, 127, 0, tmpdir
+                                        });
+    support_capture_subprocess_check (&result, "system", 0, sc_allow_stderr);
+
+    char *returnerr = xasprintf ("%s: execing %s failed: "
+                                "No such file or directory",
+                                basename(_PATH_BSHELL), cmd);
+    TEST_COMPARE_STRING (result.err.buffer, returnerr);
+    free (returnerr);
+  }
+
+  {
+    char cmd[namemax + 1];
+    memset (cmd, 'a', sizeof(cmd));
+    cmd[sizeof(cmd) - 1] = '\0';
+
+    struct support_capture_subprocess result;
+    result = support_capture_subprocess (call_system,
+                                        &(struct args) {
+                                          cmd, 127, 0, tmpdir
+                                        });
+    support_capture_subprocess_check (&result, "system", 0, sc_allow_stderr);
+
+    char *returnerr = xasprintf ("%s: execing %s failed: "
+                                "File name too long",
+                                basename(_PATH_BSHELL), cmd);
+    TEST_COMPARE_STRING (result.err.buffer, returnerr);
+    free (returnerr);
+  }
+
+  {
+    struct support_capture_subprocess result;
+    result = support_capture_subprocess (call_system,
+                                        &(struct args) {
+                                          "kill $$", 0, SIGTERM
+                                        });
+    support_capture_subprocess_check (&result, "system", 0, sc_allow_none);
+  }
+
+  {
+    struct support_capture_subprocess result;
+    result = support_capture_subprocess (call_system,
+                                        &(struct args) { "echo ...", 0 });
+    support_capture_subprocess_check (&result, "system", 0, sc_allow_stdout);
+    TEST_COMPARE_STRING (result.out.buffer, "...\n");
+  }
+
+  {
+    struct support_capture_subprocess result;
+    result = support_capture_subprocess (call_system,
+                                        &(struct args) { "exit 1", 1 });
+    support_capture_subprocess_check (&result, "system", 0, sc_allow_none);
+  }
+
+  TEST_COMPARE (system (""), 0);
+
+  return 0;
+}
 
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
index c38eea971f4396c678598f51602082318ec5349d..608ed496b99272f7668165ef6379fa7e242a5bc8 100644 (file)
@@ -33,7 +33,8 @@ __BEGIN_DECLS
 #include <stddef.h>
 
 /* Tell the caller that we provide correct C++ prototypes.  */
-#if defined __cplusplus && __GNUC_PREREQ (4, 4)
+#if defined __cplusplus && (__GNUC_PREREQ (4, 4) \
+                           || __glibc_clang_prereq (3, 5))
 # define __CORRECT_ISO_CPP_STRING_H_PROTO
 #endif
 
index df6dbc251ecf984196b8c0e75ca9f78784e1e016..daed9a2705457e9da142c07440dee64de657ca92 100644 (file)
@@ -139,16 +139,45 @@ check1 (void)
 static void
 check2 (void)
 {
-  const char s1[] = ", enable_static, \0, enable_shared, ";
+  const char s1_stack[] = ", enable_static, \0, enable_shared, ";
+  const size_t s1_byte_count = 18;
+  const char *s2_stack = &(s1_stack[s1_byte_count]);
+  const size_t s2_byte_count = 18;
   char *exp_result;
-  char *s2 = (void *) buf1 + page_size - 18;
+  const size_t page_size_real = getpagesize ();
 
-  strcpy (s2, s1);
-  exp_result = stupid_strstr (s1, s1 + 18);
+  /* Haystack at end of page.  The following page is protected.  */
+  char *s1_page_end = (void *) buf1 + page_size - s1_byte_count;
+  strcpy (s1_page_end, s1_stack);
+
+  /* Haystack which crosses a page boundary.
+     Note: page_size is at least 2 * getpagesize.  See test_init.  */
+  char *s1_page_cross = (void *) buf1 + page_size_real - 8;
+  strcpy (s1_page_cross, s1_stack);
+
+  /* Needle at end of page.  The following page is protected.  */
+  char *s2_page_end = (void *) buf2 + page_size - s2_byte_count;
+  strcpy (s2_page_end, s2_stack);
+
+  /* Needle which crosses a page boundary.
+     Note: page_size is at least 2 * getpagesize.  See test_init.  */
+  char *s2_page_cross = (void *) buf2 + page_size_real - 8;
+  strcpy (s2_page_cross, s2_stack);
+
+  exp_result = stupid_strstr (s1_stack, s2_stack);
   FOR_EACH_IMPL (impl, 0)
     {
-      check_result (impl, s1, s1 + 18, exp_result);
-      check_result (impl, s2, s1 + 18, exp_result);
+      check_result (impl, s1_stack, s2_stack, exp_result);
+      check_result (impl, s1_stack, s2_page_end, exp_result);
+      check_result (impl, s1_stack, s2_page_cross, exp_result);
+
+      check_result (impl, s1_page_end, s2_stack, exp_result);
+      check_result (impl, s1_page_end, s2_page_end, exp_result);
+      check_result (impl, s1_page_end, s2_page_cross, exp_result);
+
+      check_result (impl, s1_page_cross, s2_stack, exp_result);
+      check_result (impl, s1_page_cross, s2_page_end, exp_result);
+      check_result (impl, s1_page_cross, s2_page_cross, exp_result);
     }
 }
 
index ee3224dfd0687272bd2f184bfa939d28f3d4d1c3..51b01dce0d9f834c401dab20304840ebf110f81c 100644 (file)
@@ -135,6 +135,37 @@ copy_func (char **argv)
 
 }
 
+/* Emulate the 'exit' builtin.  The exit value is optional.  */
+static int
+exit_func (char **argv)
+{
+  int exit_val = 0;
+
+  if (argv[0] != 0)
+    exit_val = atoi (argv[0]) & 0xff;
+  exit (exit_val);
+  return 0;
+}
+
+/* Emulate the "/bin/kill" command.  Options are ignored.  */
+static int
+kill_func (char **argv)
+{
+  int signum = SIGTERM;
+  int i;
+
+  for (i = 0; argv[i]; i++)
+    {
+      pid_t pid;
+      if (strcmp (argv[i], "$$") == 0)
+       pid = getpid ();
+      else
+       pid = atoi (argv[i]);
+      kill (pid, signum);
+    }
+  return 0;
+}
+
 /* This is a list of all the built-in commands we understand.  */
 static struct {
   const char *name;
@@ -143,6 +174,8 @@ static struct {
   { "true", true_func },
   { "echo", echo_func },
   { "cp", copy_func },
+  { "exit", exit_func },
+  { "kill", kill_func },
   { NULL, NULL }
 };
 
@@ -238,7 +271,7 @@ run_command_array (char **argv)
 
       fprintf (stderr, "sh: execing %s failed: %s",
               argv[0], strerror (errno));
-      exit (1);
+      exit (127);
     }
 
   waitpid (pid, &status, 0);
@@ -251,6 +284,11 @@ run_command_array (char **argv)
       if (rv)
        exit (rv);
     }
+  else if (WIFSIGNALED (status))
+    {
+      int sig = WTERMSIG (status);
+      raise (sig);
+    }
   else
     exit (1);
 }
index 0f77dd2ed07c0d44486834bd00c7a24686f3e8b5..89c4527a8146d42695aa27e593bc731e1b807ef0 100644 (file)
@@ -1084,10 +1084,10 @@ ildouble: 1
 ldouble: 1
 
 Function: Real part of "cpow_downward":
-double: 2
-float: 4
-idouble: 2
-ifloat: 4
+double: 5
+float: 8
+idouble: 5
+ifloat: 8
 ildouble: 6
 ldouble: 6
 
@@ -1100,10 +1100,10 @@ ildouble: 2
 ldouble: 2
 
 Function: Real part of "cpow_towardzero":
-double: 2
-float: 4
-idouble: 2
-ifloat: 4
+double: 5
+float: 8
+idouble: 5
+ifloat: 8
 ildouble: 6
 ldouble: 6
 
diff --git a/sysdeps/arm/be/nofpu/Implies b/sysdeps/arm/be/nofpu/Implies
new file mode 100644 (file)
index 0000000..c90dd7f
--- /dev/null
@@ -0,0 +1 @@
+arm/nofpu
diff --git a/sysdeps/arm/le/nofpu/Implies b/sysdeps/arm/le/nofpu/Implies
new file mode 100644 (file)
index 0000000..c90dd7f
--- /dev/null
@@ -0,0 +1 @@
+arm/nofpu
index f3d862651ef22826d4752460807284cb89739bb4..724c3e5e719491699ddcca3a26c80c75052e0ff8 100644 (file)
@@ -41,6 +41,8 @@
   (void) __close (fd)
 #define __read_nocancel(fd, buf, n) \
   __read (fd, buf, n)
+#define __pread64_nocancel(fd, buf, count, offset) \
+  __pread64 (fd, buf, count, offset)
 #define __write_nocancel(fd, buf, n) \
   __write (fd, buf, n)
 #define __writev_nocancel_nostatus(fd, iov, n) \
index d077147a7a4c79e09f59497850f167f362e381e5..d61cbb33005e18ac942b450a5594349df57108a0 100644 (file)
 static int
 __utmp_equal (const struct utmp *entry, const struct utmp *match)
 {
-  return
-    (
-#if _HAVE_UT_TYPE - 0
-     (entry->ut_type == INIT_PROCESS
-      || entry->ut_type == LOGIN_PROCESS
-      || entry->ut_type == USER_PROCESS
-      || entry->ut_type == DEAD_PROCESS)
-     &&
-     (match->ut_type == INIT_PROCESS
-      || match->ut_type == LOGIN_PROCESS
-      || match->ut_type == USER_PROCESS
-      || match->ut_type == DEAD_PROCESS)
-     &&
-#endif
-#if _HAVE_UT_ID - 0
-     (entry->ut_id[0] && match->ut_id[0]
-      ? strncmp (entry->ut_id, match->ut_id, sizeof match->ut_id) == 0
-      : strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) == 0)
-#else
-     strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line) == 0
-#endif
-     );
+  return (entry->ut_type == INIT_PROCESS
+          || entry->ut_type == LOGIN_PROCESS
+          || entry->ut_type == USER_PROCESS
+          || entry->ut_type == DEAD_PROCESS)
+    && (match->ut_type == INIT_PROCESS
+        || match->ut_type == LOGIN_PROCESS
+        || match->ut_type == USER_PROCESS
+        || match->ut_type == DEAD_PROCESS)
+    && (entry->ut_id[0] && match->ut_id[0]
+        ? strncmp (entry->ut_id, match->ut_id, sizeof match->ut_id) == 0
+        : (strncmp (entry->ut_line, match->ut_line, sizeof match->ut_line)
+           == 0));
 }
diff --git a/sysdeps/gnu/bits/utmp.h b/sysdeps/gnu/bits/utmp.h
deleted file mode 100644 (file)
index 7357034..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/* The `struct utmp' type, describing entries in the utmp file.  GNU version.
-   Copyright (C) 1993-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#ifndef _UTMP_H
-# error "Never include <bits/utmp.h> directly; use <utmp.h> instead."
-#endif
-
-#include <paths.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <bits/wordsize.h>
-
-
-#define UT_LINESIZE    32
-#define UT_NAMESIZE    32
-#define UT_HOSTSIZE    256
-
-
-/* The structure describing an entry in the database of
-   previous logins.  */
-struct lastlog
-  {
-#if __WORDSIZE_TIME64_COMPAT32
-    int32_t ll_time;
-#else
-    __time_t ll_time;
-#endif
-    char ll_line[UT_LINESIZE];
-    char ll_host[UT_HOSTSIZE];
-  };
-
-
-/* The structure describing the status of a terminated process.  This
-   type is used in `struct utmp' below.  */
-struct exit_status
-  {
-    short int e_termination;   /* Process termination status.  */
-    short int e_exit;          /* Process exit status.  */
-  };
-
-
-/* The structure describing an entry in the user accounting database.  */
-struct utmp
-{
-  short int ut_type;           /* Type of login.  */
-  pid_t ut_pid;                        /* Process ID of login process.  */
-  char ut_line[UT_LINESIZE]
-    __attribute_nonstring__;   /* Devicename.  */
-  char ut_id[4];               /* Inittab ID.  */
-  char ut_user[UT_NAMESIZE]
-    __attribute_nonstring__;   /* Username.  */
-  char ut_host[UT_HOSTSIZE]
-    __attribute_nonstring__;   /* Hostname for remote login.  */
-  struct exit_status ut_exit;  /* Exit status of a process marked
-                                  as DEAD_PROCESS.  */
-/* The ut_session and ut_tv fields must be the same size when compiled
-   32- and 64-bit.  This allows data files and shared memory to be
-   shared between 32- and 64-bit applications.  */
-#if __WORDSIZE_TIME64_COMPAT32
-  int32_t ut_session;          /* Session ID, used for windowing.  */
-  struct
-  {
-    int32_t tv_sec;            /* Seconds.  */
-    int32_t tv_usec;           /* Microseconds.  */
-  } ut_tv;                     /* Time entry was made.  */
-#else
-  long int ut_session;         /* Session ID, used for windowing.  */
-  struct timeval ut_tv;                /* Time entry was made.  */
-#endif
-
-  int32_t ut_addr_v6[4];       /* Internet address of remote host.  */
-  char __glibc_reserved[20];           /* Reserved for future use.  */
-};
-
-/* Backwards compatibility hacks.  */
-#define ut_name                ut_user
-#ifndef _NO_UT_TIME
-/* We have a problem here: `ut_time' is also used otherwise.  Define
-   _NO_UT_TIME if the compiler complains.  */
-# define ut_time       ut_tv.tv_sec
-#endif
-#define ut_xtime       ut_tv.tv_sec
-#define ut_addr                ut_addr_v6[0]
-
-
-/* Values for the `ut_type' field of a `struct utmp'.  */
-#define EMPTY          0       /* No valid user accounting information.  */
-
-#define RUN_LVL                1       /* The system's runlevel.  */
-#define BOOT_TIME      2       /* Time of system boot.  */
-#define NEW_TIME       3       /* Time after system clock changed.  */
-#define OLD_TIME       4       /* Time when system clock changed.  */
-
-#define INIT_PROCESS   5       /* Process spawned by the init process.  */
-#define LOGIN_PROCESS  6       /* Session leader of a logged in user.  */
-#define USER_PROCESS   7       /* Normal process.  */
-#define DEAD_PROCESS   8       /* Terminated process.  */
-
-#define ACCOUNTING     9
-
-/* Old Linux name for the EMPTY type.  */
-#define UT_UNKNOWN     EMPTY
-
-
-/* Tell the user that we have a modern system with UT_HOST, UT_PID,
-   UT_TYPE, UT_ID and UT_TV fields.  */
-#define _HAVE_UT_TYPE  1
-#define _HAVE_UT_PID   1
-#define _HAVE_UT_ID    1
-#define _HAVE_UT_TV    1
-#define _HAVE_UT_HOST  1
index 472a7d57d3f99eb35cae99d58faa31745bf74812..2beadbf58707e587d980c68225851322ea6404da 100644 (file)
@@ -56,10 +56,14 @@ struct utmpx
 {
   short int ut_type;           /* Type of login.  */
   __pid_t ut_pid;              /* Process ID of login process.  */
-  char ut_line[__UT_LINESIZE]; /* Devicename.  */
-  char ut_id[4];               /* Inittab ID. */
-  char ut_user[__UT_NAMESIZE]; /* Username.  */
-  char ut_host[__UT_HOSTSIZE]; /* Hostname for remote login.  */
+  char ut_line[__UT_LINESIZE]
+    __attribute_nonstring__;   /* Devicename.  */
+  char ut_id[4]
+    __attribute_nonstring__;   /* Inittab ID.  */
+  char ut_user[__UT_NAMESIZE]
+    __attribute_nonstring__;   /* Username.  */
+  char ut_host[__UT_HOSTSIZE]
+    __attribute_nonstring__;   /* Hostname for remote login.  */
   struct __exit_status ut_exit;        /* Exit status of a process marked
                                   as DEAD_PROCESS.  */
 
index af1acb0701a9378f974130a1699baab63694314f..e01e0fff6eaf6cb86b305669c003b3c4a0644839 100644 (file)
@@ -172,8 +172,8 @@ make_fdesc (ElfW(Addr) ip, ElfW(Addr) gp)
     }
 
  install:
-  fdesc->ip = ip;
   fdesc->gp = gp;
+  fdesc->ip = ip;
 
   return (ElfW(Addr)) fdesc;
 }
@@ -350,7 +350,9 @@ ElfW(Addr)
 _dl_lookup_address (const void *address)
 {
   ElfW(Addr) addr = (ElfW(Addr)) address;
-  unsigned int *desc, *gptr;
+  ElfW(Word) reloc_arg;
+  volatile unsigned int *desc;
+  unsigned int *gptr;
 
   /* Return ADDR if the least-significant two bits of ADDR are not consistent
      with ADDR being a linker defined function pointer.  The normal value for
@@ -367,7 +369,11 @@ _dl_lookup_address (const void *address)
   if (!_dl_read_access_allowed (desc))
     return addr;
 
-  /* Load first word of candidate descriptor.  It should be a pointer
+  /* First load the relocation offset.  */
+  reloc_arg = (ElfW(Word)) desc[1];
+  atomic_full_barrier();
+
+  /* Then load first word of candidate descriptor.  It should be a pointer
      with word alignment and point to memory that can be read.  */
   gptr = (unsigned int *) desc[0];
   if (((unsigned int) gptr & 3) != 0
@@ -377,8 +383,8 @@ _dl_lookup_address (const void *address)
   /* See if descriptor requires resolution.  The following trampoline is
      used in each global offset table for function resolution:
 
-               ldw 0(r20),r22
-               bv r0(r22)
+               ldw 0(r20),r21
+               bv r0(r21)
                ldw 4(r20),r21
      tramp:    b,l .-12,r20
                depwi 0,31,2,r20
@@ -389,7 +395,15 @@ _dl_lookup_address (const void *address)
   if (gptr[0] == 0xea9f1fdd                    /* b,l .-12,r20     */
       && gptr[1] == 0xd6801c1e                 /* depwi 0,31,2,r20 */
       && (ElfW(Addr)) gptr[2] == elf_machine_resolve ())
-    _dl_fixup ((struct link_map *) gptr[5], (ElfW(Word)) desc[1]);
+    {
+      struct link_map *l = (struct link_map *) gptr[5];
+
+      /* If gp has been resolved, we need to hunt for relocation offset.  */
+      if (!(reloc_arg & PA_GP_RELOC))
+       reloc_arg = _dl_fix_reloc_arg (addr, l);
+
+      _dl_fixup (l, reloc_arg);
+    }
 
   return (ElfW(Addr)) desc[0];
 }
index 509c5411238c13245c0ba7932a01af245cebbdad..b80b60bdba68a9f8c72cb1a8aa824b0c10fbdda2 100644 (file)
 #define GOT_FROM_PLT_STUB (4*4)
 #define PLT_ENTRY_SIZE (2*4)
 
+/* The gp slot in the function descriptor contains the relocation offset
+   before resolution.  To distinguish between a resolved gp value and an
+   unresolved relocation offset we set an unused bit in the relocation
+   offset.  This would allow us to do a synchronzied two word update
+   using this bit (interlocked update), but instead of waiting for the
+   update we simply recompute the gp value given that we know the ip.  */
+#define PA_GP_RELOC 1
+
 /* Initialize the function descriptor table before relocations */
 static inline void
 __hppa_init_bootstrap_fdesc_table (struct link_map *map)
@@ -117,10 +125,28 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
   volatile Elf32_Addr *rfdesc = reloc_addr;
   /* map is the link_map for the caller, t is the link_map for the object
      being called */
-  rfdesc[1] = value.gp;
-  /* Need to ensure that the gp is visible before the code
-     entry point is updated */
-  rfdesc[0] = value.ip;
+
+  /* We would like the function descriptor to be double word aligned.  This
+     helps performance (ip and gp then reside on the same cache line) and
+     we can update the pair atomically with a single store.  The linker
+     now ensures this alignment but we still have to handle old code.  */
+  if ((unsigned int)reloc_addr & 7)
+    {
+      /* Need to ensure that the gp is visible before the code
+         entry point is updated */
+      rfdesc[1] = value.gp;
+      atomic_full_barrier();
+      rfdesc[0] = value.ip;
+    }
+  else
+    {
+      /* Update pair atomically with floating point store.  */
+      union { ElfW(Word) v[2]; double d; } u;
+
+      u.v[0] = value.ip;
+      u.v[1] = value.gp;
+      *(volatile double *)rfdesc = u.d;
+    }
   return value;
 }
 
@@ -265,7 +291,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
                     here.  The trampoline code will load the proper
                     LTP and pass the reloc offset to the fixup
                     function.  */
-                 fptr->gp = iplt - jmprel;
+                 fptr->gp = (iplt - jmprel) | PA_GP_RELOC;
                } /* r_sym != 0 */
              else
                {
diff --git a/sysdeps/hppa/dl-runtime.c b/sysdeps/hppa/dl-runtime.c
new file mode 100644 (file)
index 0000000..885a3f1
--- /dev/null
@@ -0,0 +1,58 @@
+/* On-demand PLT fixup for shared objects.  HPPA version.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* Clear PA_GP_RELOC bit in relocation offset.  */
+#define reloc_offset (reloc_arg & ~PA_GP_RELOC)
+#define reloc_index  (reloc_arg & ~PA_GP_RELOC) / sizeof (PLTREL)
+
+#include <elf/dl-runtime.c>
+
+/* The caller has encountered a partially relocated function descriptor.
+   The gp of the descriptor has been updated, but not the ip.  We find
+   the function descriptor again and compute the relocation offset and
+   return that to the caller.  The caller will continue on to call
+   _dl_fixup with the relocation offset.  */
+
+ElfW(Word)
+attribute_hidden __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
+_dl_fix_reloc_arg (struct fdesc *fptr, struct link_map *l)
+{
+  Elf32_Addr l_addr, iplt, jmprel, end_jmprel, r_type;
+  const Elf32_Rela *reloc;
+
+  l_addr = l->l_addr;
+  jmprel = D_PTR(l, l_info[DT_JMPREL]);
+  end_jmprel = jmprel + l->l_info[DT_PLTRELSZ]->d_un.d_val;
+
+  /* Look for the entry...  */
+  for (iplt = jmprel; iplt < end_jmprel; iplt += sizeof (Elf32_Rela))
+    {
+      reloc = (const Elf32_Rela *) iplt;
+      r_type = ELF32_R_TYPE (reloc->r_info);
+
+      if (__builtin_expect (r_type == R_PARISC_IPLT, 1)
+         && fptr == (struct fdesc *) (reloc->r_offset + l_addr))
+       /* Found entry. Return the reloc offset.  */
+       return iplt - jmprel;
+    }
+
+  /* Crash if we weren't passed a valid function pointer.  */
+  ABORT_INSTRUCTION;
+  return 0;
+}
index 6df2852038a5419a2c2c2915fc1d9b1bc3e62ea3..f0f0fefad57df16c6c712681a6acd0fd5efaf1be 100644 (file)
@@ -31,7 +31,7 @@
    slow down __cffc when it attempts to call fixup to resolve function
    descriptor references. Please refer to gcc/gcc/config/pa/fptr.c
 
-   Enter with r19 = reloc offset, r20 = got-8, r21 = fixup ltp.  */
+   Enter with r19 = reloc offset, r20 = got-8, r21 = fixup ltp, r22 = fp.  */
 
        /* RELOCATION MARKER: bl to provide gcc's __cffc with fixup loc. */
        .text
@@ -61,17 +61,20 @@ _dl_runtime_resolve:
        copy    %sp, %r1        /* Copy previous sp */
        /* Save function result address (on entry) */
        stwm    %r28,128(%sp)
-       /* Fillin some frame info to follow ABI */
+       /* Fill in some frame info to follow ABI */
        stw     %r1,-4(%sp)     /* Previous sp */
        stw     %r21,-32(%sp)   /* PIC register value */
 
        /* Save input floating point registers. This must be done
           in the new frame since the previous frame doesn't have
           enough space */
-       ldo     -56(%sp),%r1
+       ldo     -64(%sp),%r1
        fstd,ma %fr4,-8(%r1)
        fstd,ma %fr5,-8(%r1)
        fstd,ma %fr6,-8(%r1)
+
+       /* Test PA_GP_RELOC bit.  */
+       bb,>=   %r19,31,2f              /* branch if not reloc offset */
        fstd,ma %fr7,-8(%r1)
 
        /* Set up args to fixup func, needs only two arguments  */
@@ -79,7 +82,7 @@ _dl_runtime_resolve:
        copy    %r19,%r25               /* (2) reloc offset  */
 
        /* Call the real address resolver. */
-       bl      _dl_fixup,%rp
+3:     bl      _dl_fixup,%rp
        copy    %r21,%r19               /* set fixup func ltp */
 
        /* While the linker will set a function pointer to NULL when it
@@ -102,7 +105,7 @@ _dl_runtime_resolve:
        copy    %r29, %r19
 
        /* Reload arguments fp args */
-       ldo     -56(%sp),%r1
+       ldo     -64(%sp),%r1
        fldd,ma -8(%r1),%fr4
        fldd,ma -8(%r1),%fr5
        fldd,ma -8(%r1),%fr6
@@ -129,6 +132,25 @@ _dl_runtime_resolve:
        bv      %r0(%rp)
        ldo     -128(%sp),%sp
 
+2:
+       /* Set up args for _dl_fix_reloc_arg.  */
+       copy    %r22,%r26               /* (1) function pointer */
+       depi    0,31,2,%r26             /* clear least significant bits */
+       ldw     8+4(%r20),%r25          /* (2) got[1] == struct link_map */
+
+       /* Save ltp and link map arg for _dl_fixup.  */
+       stw     %r21,-56(%sp)           /* ltp */
+       stw     %r25,-60(%sp)           /* struct link map */
+
+       /* Find reloc offset. */
+       bl      _dl_fix_reloc_arg,%rp
+       copy    %r21,%r19               /* set func ltp */
+
+       /* Set up args for _dl_fixup.  */
+       ldw     -56(%sp),%r21           /* ltp */
+       ldw     -60(%sp),%r26           /* (1) struct link map */
+       b       3b
+       copy    %ret0,%r25              /* (2) reloc offset */
         .EXIT
         .PROCEND
        cfi_endproc
@@ -153,7 +175,7 @@ _dl_runtime_profile:
        copy    %sp, %r1        /* Copy previous sp */
        /* Save function result address (on entry) */
        stwm    %r28,192(%sp)
-       /* Fillin some frame info to follow ABI */
+       /* Fill in some frame info to follow ABI */
        stw     %r1,-4(%sp)     /* Previous sp */
        stw     %r21,-32(%sp)   /* PIC register value */
 
@@ -181,10 +203,11 @@ _dl_runtime_profile:
        fstd,ma %fr5,8(%r1)
        fstd,ma %fr6,8(%r1)
        fstd,ma %fr7,8(%r1)
-       /* 32-bit stack pointer and return register */
-       stw     %sp,-56(%sp)
-       stw     %r2,-52(%sp)
 
+       /* Test PA_GP_RELOC bit.  */
+       bb,>=   %r19,31,2f              /* branch if not reloc offset */
+       /* 32-bit stack pointer */
+       stw     %sp,-56(%sp)
 
        /* Set up args to fixup func, needs five arguments  */
        ldw     8+4(%r20),%r26          /* (1) got[1] == struct link_map */
@@ -197,7 +220,7 @@ _dl_runtime_profile:
        stw     %r1, -52(%sp)           /* (5) long int *framesizep */
 
        /* Call the real address resolver. */
-       bl      _dl_profile_fixup,%rp
+3:     bl      _dl_profile_fixup,%rp
        copy    %r21,%r19               /* set fixup func ltp */
 
        /* Load up the returned function descriptor */
@@ -215,7 +238,9 @@ _dl_runtime_profile:
        fldd,ma 8(%r1),%fr5
        fldd,ma 8(%r1),%fr6
        fldd,ma 8(%r1),%fr7
-       ldw     -52(%sp),%rp
+
+       /* Reload rp register -(192+20) without adjusting stack */
+       ldw     -212(%sp),%rp
 
        /* Reload static link register -(192+16) without adjusting stack */
        ldw     -208(%sp),%r29
@@ -303,6 +328,33 @@ L(cont):
         ldw -20(%sp),%rp
        /* Return */
        bv,n    0(%r2)
+
+2:
+       /* Set up args for _dl_fix_reloc_arg.  */
+       copy    %r22,%r26               /* (1) function pointer */
+       depi    0,31,2,%r26             /* clear least significant bits */
+       ldw     8+4(%r20),%r25          /* (2) got[1] == struct link_map */
+
+       /* Save ltp and link map arg for _dl_fixup.  */
+       stw     %r21,-92(%sp)           /* ltp */
+       stw     %r25,-116(%sp)          /* struct link map */
+
+       /* Find reloc offset. */
+       bl      _dl_fix_reloc_arg,%rp
+       copy    %r21,%r19               /* set func ltp */
+
+        /* Restore fixup ltp.  */
+       ldw     -92(%sp),%r21           /* ltp */
+
+       /* Set up args to fixup func, needs five arguments  */
+       ldw     -116(%sp),%r26          /* (1) struct link map */
+       copy    %ret0,%r25              /* (2) reloc offset  */
+       stw     %r25,-120(%sp)          /* Save reloc offset */
+       ldw     -212(%sp),%r24          /* (3) profile_fixup needs rp */
+       ldo     -56(%sp),%r23           /* (4) La_hppa_regs */
+       ldo     -112(%sp), %r1
+       b       3b
+       stw     %r1, -52(%sp)           /* (5) long int *framesizep */
         .EXIT
         .PROCEND
        cfi_endproc
index d0c4dea001f596356de177fbb94f1e04aaf9e012..2c61a7ae912f86aba6ed00c4d3e68c0de4da9130 100644 (file)
@@ -544,9 +544,9 @@ idouble: 1
 ifloat: 1
 
 Function: Imaginary part of "ccos_downward":
-double: 2
+double: 3
 float: 3
-idouble: 2
+idouble: 3
 ifloat: 3
 
 Function: Real part of "ccos_towardzero":
@@ -556,9 +556,9 @@ idouble: 1
 ifloat: 2
 
 Function: Imaginary part of "ccos_towardzero":
-double: 2
+double: 3
 float: 3
-idouble: 2
+idouble: 3
 ifloat: 3
 
 Function: Real part of "ccos_upward":
@@ -588,27 +588,27 @@ idouble: 1
 ifloat: 1
 
 Function: Real part of "ccosh_downward":
-double: 1
+double: 2
 float: 3
-idouble: 1
+idouble: 2
 ifloat: 3
 
 Function: Imaginary part of "ccosh_downward":
-double: 2
+double: 3
 float: 3
-idouble: 2
+idouble: 3
 ifloat: 3
 
 Function: Real part of "ccosh_towardzero":
-double: 1
+double: 2
 float: 3
-idouble: 1
+idouble: 2
 ifloat: 3
 
 Function: Imaginary part of "ccosh_towardzero":
-double: 2
+double: 3
 float: 3
-idouble: 2
+idouble: 3
 ifloat: 3
 
 Function: Real part of "ccosh_upward":
@@ -636,27 +636,27 @@ idouble: 1
 ifloat: 2
 
 Function: Real part of "cexp_downward":
-double: 1
+double: 2
 float: 2
-idouble: 1
+idouble: 2
 ifloat: 2
 
 Function: Imaginary part of "cexp_downward":
-double: 1
+double: 3
 float: 3
-idouble: 1
+idouble: 3
 ifloat: 3
 
 Function: Real part of "cexp_towardzero":
-double: 1
+double: 2
 float: 2
-idouble: 1
+idouble: 2
 ifloat: 2
 
 Function: Imaginary part of "cexp_towardzero":
-double: 1
+double: 3
 float: 3
-idouble: 1
+idouble: 3
 ifloat: 3
 
 Function: Real part of "cexp_upward":
@@ -666,9 +666,9 @@ idouble: 1
 ifloat: 2
 
 Function: Imaginary part of "cexp_upward":
-double: 1
+double: 3
 float: 2
-idouble: 1
+idouble: 3
 ifloat: 2
 
 Function: Real part of "clog":
@@ -800,21 +800,21 @@ idouble: 1
 ifloat: 1
 
 Function: "cosh_downward":
-double: 1
+double: 2
 float: 1
-idouble: 1
+idouble: 2
 ifloat: 1
 
 Function: "cosh_towardzero":
-double: 1
+double: 2
 float: 1
-idouble: 1
+idouble: 2
 ifloat: 1
 
 Function: "cosh_upward":
-double: 1
+double: 2
 float: 2
-idouble: 1
+idouble: 2
 ifloat: 2
 
 Function: Real part of "cpow":
@@ -834,9 +834,9 @@ ildouble: 2
 ldouble: 2
 
 Function: Real part of "cpow_downward":
-double: 4
+double: 5
 float: 8
-idouble: 4
+idouble: 5
 ifloat: 8
 
 Function: Imaginary part of "cpow_downward":
@@ -846,9 +846,9 @@ idouble: 2
 ifloat: 2
 
 Function: Real part of "cpow_towardzero":
-double: 4
+double: 5
 float: 8
-idouble: 4
+idouble: 5
 ifloat: 8
 
 Function: Imaginary part of "cpow_towardzero":
@@ -876,9 +876,9 @@ idouble: 1
 ifloat: 1
 
 Function: Real part of "csin_downward":
-double: 2
+double: 3
 float: 3
-idouble: 2
+idouble: 3
 ifloat: 3
 
 Function: Imaginary part of "csin_downward":
@@ -888,9 +888,9 @@ idouble: 1
 ifloat: 2
 
 Function: Real part of "csin_towardzero":
-double: 2
+double: 3
 float: 3
-idouble: 2
+idouble: 3
 ifloat: 3
 
 Function: Imaginary part of "csin_towardzero":
@@ -930,9 +930,9 @@ idouble: 2
 ifloat: 2
 
 Function: Imaginary part of "csinh_downward":
-double: 2
+double: 3
 float: 3
-idouble: 2
+idouble: 3
 ifloat: 3
 
 Function: Real part of "csinh_towardzero":
@@ -942,9 +942,9 @@ idouble: 2
 ifloat: 2
 
 Function: Imaginary part of "csinh_towardzero":
-double: 2
+double: 3
 float: 3
-idouble: 2
+idouble: 3
 ifloat: 3
 
 Function: Real part of "csinh_upward":
@@ -1172,15 +1172,15 @@ ildouble: 6
 ldouble: 6
 
 Function: "exp10_downward":
-double: 2
+double: 3
 float: 1
-idouble: 2
+idouble: 3
 ifloat: 1
 
 Function: "exp10_towardzero":
-double: 2
+double: 3
 float: 1
-idouble: 2
+idouble: 3
 ifloat: 1
 
 Function: "exp10_upward":
index 749b55b07787f4bc4f3e426eb2f197cc2b702ca1..eee6d586c1b831d31afebc53a72fab04e135e804 100644 (file)
@@ -61,7 +61,7 @@ lose: SYSCALL_PIC_SETUP                                                             \
 
 # define SETUP_PIC_REG(reg) \
   .ifndef GET_PC_THUNK(reg);                                                 \
-  .section .gnu.linkonce.t.GET_PC_THUNK(reg),"ax",@progbits;                 \
+  .section .text.GET_PC_THUNK(reg),"axG",@progbits,GET_PC_THUNK(reg),comdat;  \
   .globl GET_PC_THUNK(reg);                                                  \
   .hidden GET_PC_THUNK(reg);                                                 \
   .p2align 4;                                                                \
@@ -97,7 +97,8 @@ GET_PC_THUNK(reg):                                                          \
 
 # define SETUP_PIC_REG_STR(reg)                                                \
   ".ifndef " GET_PC_THUNK_STR (reg) "\n"                               \
-  ".section .gnu.linkonce.t." GET_PC_THUNK_STR (reg) ",\"ax\",@progbits\n" \
+  ".section .text." GET_PC_THUNK_STR (reg) ",\"axG\",@progbits,"       \
+    GET_PC_THUNK_STR (reg) ",comdat\n"                                 \
   ".globl " GET_PC_THUNK_STR (reg) "\n"                                        \
   ".hidden " GET_PC_THUNK_STR (reg) "\n"                               \
   ".p2align 4\n"                                                       \
index b10325421403b6c45372414419f765ca88d3f380..4142695ec89be59928948f0f5f70dc510111fe8b 100644 (file)
@@ -17,5 +17,8 @@
 # <http://www.gnu.org/licenses/>.
 
 ifeq ($(subdir),math)
-tests += test-canonical-ldbl-96 test-totalorderl-ldbl-96
+tests += test-canonical-ldbl-96 test-totalorderl-ldbl-96 test-sinl-pseudo
+ifeq ($(have-ssp),yes)
+CFLAGS-test-sinl-pseudo.c += -fstack-protector-all
 endif
+endif # $(subdir) == math
index 805de22d732f330869e255c32ec356c9102174b7..1aeccb47d729f54341679260269e3726ca531e32 100644 (file)
@@ -210,6 +210,18 @@ __ieee754_rem_pio2l (long double x, long double *y)
       return 0;
     }
 
+  if ((i0 & 0x80000000) == 0)
+    {
+      /* Pseudo-zero and unnormal representations are not valid
+        representations of long double.  We need to avoid stack
+        corruption in __kernel_rem_pio2, which expects input in a
+        particular normal form, but those representations do not need
+        to be consistently handled like any particular floating-point
+        value.  */
+      y[1] = y[0] = __builtin_nanl ("");
+      return 0;
+    }
+
   /* Split the 64 bits of the mantissa into three 24-bit integers
      stored in a double array.  */
   exp = j0 - 23;
diff --git a/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c b/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c
new file mode 100644 (file)
index 0000000..f59b977
--- /dev/null
@@ -0,0 +1,41 @@
+/* Test sinl for pseudo-zeros and unnormals for ldbl-96 (bug 25487).
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_ldbl.h>
+#include <stdint.h>
+
+static int
+do_test (void)
+{
+  for (int i = 0; i < 64; i++)
+    {
+      uint64_t sig = i == 63 ? 0 : 1ULL << i;
+      long double ld;
+      SET_LDOUBLE_WORDS (ld, 0x4141,
+                        sig >> 32, sig & 0xffffffffULL);
+      /* The requirement is that no stack overflow occurs when the
+        pseudo-zero or unnormal goes through range reduction.  */
+      volatile long double ldr;
+      ldr = sinl (ld);
+      (void) ldr;
+    }
+  return 0;
+}
+
+#include <support/test-driver.c>
index a08d328b2397a5f7d41eefb80c5e83e151ad4baf..863d7c016fb36d317e95a923d412e958ef910880 100644 (file)
@@ -97,7 +97,8 @@ cancel_handler (void *arg)
 static int
 do_system (const char *line)
 {
-  int status;
+  int status = -1;
+  int ret;
   pid_t pid;
   struct sigaction sa;
 #ifndef _LIBC_REENTRANT
@@ -140,14 +141,14 @@ do_system (const char *line)
   __posix_spawnattr_setflags (&spawn_attr,
                              POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK);
 
-  status = __posix_spawn (&pid, SHELL_PATH, 0, &spawn_attr,
-                         (char *const[]){ (char*) SHELL_NAME,
-                                          (char*) "-c",
-                                          (char *) line, NULL },
-                         __environ);
+  ret = __posix_spawn (&pid, SHELL_PATH, 0, &spawn_attr,
+                      (char *const[]){ (char *) SHELL_NAME,
+                                       (char *) "-c",
+                                       (char *) line, NULL },
+                      __environ);
   __posix_spawnattr_destroy (&spawn_attr);
 
-  if (status == 0)
+  if (ret == 0)
     {
       /* Cancellation results in cleanup handlers running as exceptions in
         the block where they were installed, so it is safe to reference
@@ -182,6 +183,9 @@ do_system (const char *line)
     }
   DO_UNLOCK ();
 
+  if (ret != 0)
+    __set_errno (ret);
+
   return status;
 }
 
index 857a8aad7b996a4263845f5f8ed2dc538493a99b..dc187a8f202874568beb94003191da0c0fce5e30 100644 (file)
@@ -114,6 +114,8 @@ __backtrace (void **array, int size)
         }
       if (gregset)
        {
+         if (count + 1 == size)
+           break;
          array[++count] = (void*)((*gregset)[PT_NIP]);
          current = (void*)((*gregset)[PT_R1]);
        }
index 7a167838d913c25742e65ff7a1e2fdd533566528..ce038a139faa2e23833668d1ba14d9a15d343556 100644 (file)
@@ -87,6 +87,8 @@ __backtrace (void **array, int size)
       if (is_sigtramp_address (current->return_address))
         {
          struct signal_frame_64 *sigframe = (struct signal_frame_64*) current;
+         if (count + 1 == size)
+           break;
           array[++count] = (void*) sigframe->uc.uc_mcontext.gp_regs[PT_NIP];
          current = (void*) sigframe->uc.uc_mcontext.gp_regs[PT_R1];
        }
index 44c99018000abf444cebc898f6f62537d631b437..1307ec41def105ad4e8f71c08884f6908ce8032e 100644 (file)
@@ -63,11 +63,11 @@ PROCINFO_CLASS const char _dl_s390_cap_flags[19][9]
 #if !defined PROCINFO_DECL && defined SHARED
   ._dl_s390_platforms
 #else
-PROCINFO_CLASS const char _dl_s390_platforms[9][7]
+PROCINFO_CLASS const char _dl_s390_platforms[10][7]
 #endif
 #ifndef PROCINFO_DECL
 = {
-    "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14"
+    "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14", "z15"
   }
 #endif
 #if !defined SHARED || defined PROCINFO_DECL
index 3b1f6a642bbf21f3c5808462ab7d4ee511fc947b..689e961ced92a9c2cf9c5240d32bab0c7464eac9 100644 (file)
@@ -23,7 +23,7 @@
 
 #define _DL_HWCAP_COUNT 19
 
-#define _DL_PLATFORMS_COUNT    9
+#define _DL_PLATFORMS_COUNT    10
 
 /* The kernel provides up to 32 capability bits with elf_hwcap.  */
 #define _DL_FIRST_PLATFORM     32
index 929b026adfeba740b6275ef70ce3b4c883c3669b..faa969849e09c2e1de873be2b41af020884d7b40 100644 (file)
@@ -164,7 +164,7 @@ ENTRY(STRSTR_ARCH13)
        vfenezb %v19,%v18,%v18  /* Search zero in loaded needle bytes.  */
        veclb   %v19,%v21       /* Zero index <= max loaded byte index?  */
        jle     .Lneedle_loaded /* -> v18 contains full needle.  */
-       vl      %v16,0(%r3)     /* Load needle beyond page boundary.  */
+       vl      %v18,0(%r3)     /* Load needle beyond page boundary.  */
        vfenezb %v19,%v18,%v18
        j       .Lneedle_loaded
 END(STRSTR_ARCH13)
diff --git a/sysdeps/unix/alpha/getegid.S b/sysdeps/unix/alpha/getegid.S
deleted file mode 100644 (file)
index 167009d..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-
-
-PSEUDO (__getegid, getxgid, 0)
-       MOVE (r1, r0)
-       ret
-PSEUDO_END (__getegid)
-
-weak_alias (__getegid, getegid)
diff --git a/sysdeps/unix/alpha/geteuid.S b/sysdeps/unix/alpha/geteuid.S
deleted file mode 100644 (file)
index 3941377..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-
-
-PSEUDO (__geteuid, getxuid, 0)
-       MOVE (r1, r0)
-       ret
-PSEUDO_END (__geteuid)
-
-weak_alias (__geteuid, geteuid)
diff --git a/sysdeps/unix/alpha/getppid.S b/sysdeps/unix/alpha/getppid.S
deleted file mode 100644 (file)
index 4d29118..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-
-
-PSEUDO (__getppid, getxpid, 0)
-       MOVE (r1, r0)
-       ret
-PSEUDO_END (__getppid)
-
-weak_alias (__getppid, getppid)
index 6c564d3b5959a97c448e99fcd626ff65ab750aa2..88971a9931e494d12f4b7b689b07157439cf89a8 100644 (file)
@@ -64,8 +64,8 @@ __getlogin_r (char *name, size_t name_len)
      held so that our search is thread-safe.  */
 
   __libc_lock_lock (__libc_utmp_lock);
-  (*__libc_utmp_jump_table->setutent) ();
-  result = (*__libc_utmp_jump_table->getutline_r) (&line, &buffer, &ut);
+  __libc_setutent ();
+  result = __libc_getutline_r (&line, &buffer, &ut);
   if (result < 0)
     {
       if (errno == ESRCH)
@@ -74,8 +74,7 @@ __getlogin_r (char *name, size_t name_len)
       else
        result = errno;
     }
-  (*__libc_utmp_jump_table->endutent) ();
-  __libc_utmp_jump_table = &__libc_utmp_unknown_functions;
+  __libc_endutent ();
   __libc_lock_unlock (__libc_utmp_lock);
 
   if (result == 0)
index 1ab6bcbfc815782e0633987d1fa7f3a9bfdf13c3..a7980a60f69e5767d3be75a6d002259bb828382c 100644 (file)
@@ -212,8 +212,8 @@ sysdep_routines += xstatconv internal_statvfs internal_statvfs64 \
                   close_nocancel fcntl_nocancel nanosleep_nocancel \
                   open_nocancel open64_nocancel \
                   openat_nocancel openat64_nocancel \
-                  pause_nocancel read_nocancel waitpid_nocancel \
-                  write_nocancel statx_cp
+                  pause_nocancel read_nocancel pread64_nocancel \
+                  waitpid_nocancel write_nocancel statx_cp
 
 sysdep_headers += bits/fcntl-linux.h
 
index 1ca102a9e2ed9c2bcf7a56d583e3bea6f86b81a7..d385085c611aabe4e3104c9836a9c5c66f0334d2 100644 (file)
@@ -182,6 +182,7 @@ libc {
     __syscall_rt_sigqueueinfo;
     __open_nocancel;
     __read_nocancel;
+    __pread64_nocancel;
     __close_nocancel;
     __sigtimedwait;
     # functions used by nscd
diff --git a/sysdeps/unix/sysv/linux/alpha/getegid.S b/sysdeps/unix/sysv/linux/alpha/getegid.S
new file mode 100644 (file)
index 0000000..167009d
--- /dev/null
@@ -0,0 +1,26 @@
+/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+
+PSEUDO (__getegid, getxgid, 0)
+       MOVE (r1, r0)
+       ret
+PSEUDO_END (__getegid)
+
+weak_alias (__getegid, getegid)
diff --git a/sysdeps/unix/sysv/linux/alpha/geteuid.S b/sysdeps/unix/sysv/linux/alpha/geteuid.S
new file mode 100644 (file)
index 0000000..3941377
--- /dev/null
@@ -0,0 +1,26 @@
+/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+
+PSEUDO (__geteuid, getxuid, 0)
+       MOVE (r1, r0)
+       ret
+PSEUDO_END (__geteuid)
+
+weak_alias (__geteuid, geteuid)
diff --git a/sysdeps/unix/sysv/linux/alpha/getppid.S b/sysdeps/unix/sysv/linux/alpha/getppid.S
new file mode 100644 (file)
index 0000000..4d29118
--- /dev/null
@@ -0,0 +1,26 @@
+/* Copyright (C) 1991-2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+
+PSEUDO (__getppid, getxpid, 0)
+       MOVE (r1, r0)
+       ret
+PSEUDO_END (__getppid)
+
+weak_alias (__getppid, getppid)
index 206878723fd37881378df0c657ae990a19282bde..aaccfdc2dc03a1dc9aeb93183b971f27382c1092 100644 (file)
 
 /* Use "" to work around incorrect macro expansion of the
    __has_include argument (GCC PR 80005).  */
-#if __glibc_has_include ("linux/stat.h")
-# include "linux/stat.h"
-# ifdef STATX_TYPE
-#  define __statx_timestamp_defined 1
-#  define __statx_defined 1
+#ifdef __has_include
+# if __has_include ("linux/stat.h")
+#  include "linux/stat.h"
+#  ifdef STATX_TYPE
+#   define __statx_timestamp_defined 1
+#   define __statx_defined 1
+#  endif
 # endif
 #endif
 
index 222079499b0f6d15a7c9f4da176dfbc89fd3b87c..c12888fa221a2810ac55ed58efca4f4f2b70a03b 100644 (file)
@@ -36,9 +36,37 @@ typedef uintptr_t uatomicptr_t;
 typedef intmax_t atomic_max_t;
 typedef uintmax_t uatomic_max_t;
 
+#define atomic_full_barrier() __sync_synchronize ()
+
 #define __HAVE_64B_ATOMICS 0
 #define USE_ATOMIC_COMPILER_BUILTINS 0
 
+/* We use the compiler atomic load and store builtins as the generic
+   defines are not atomic.  In particular, we need to use compare and
+   exchange for stores as the implementation is synthesized.  */
+void __atomic_link_error (void);
+#define __atomic_check_size_ls(mem) \
+ if ((sizeof (*mem) != 1) && (sizeof (*mem) != 2) && sizeof (*mem) != 4)    \
+   __atomic_link_error ();
+
+#define atomic_load_relaxed(mem) \
+ ({ __atomic_check_size_ls((mem));                                           \
+    __atomic_load_n ((mem), __ATOMIC_RELAXED); })
+#define atomic_load_acquire(mem) \
+ ({ __atomic_check_size_ls((mem));                                           \
+    __atomic_load_n ((mem), __ATOMIC_ACQUIRE); })
+
+#define atomic_store_relaxed(mem, val) \
+ do {                                                                        \
+   __atomic_check_size_ls((mem));                                            \
+   __atomic_store_n ((mem), (val), __ATOMIC_RELAXED);                        \
+ } while (0)
+#define atomic_store_release(mem, val) \
+ do {                                                                        \
+   __atomic_check_size_ls((mem));                                            \
+   __atomic_store_n ((mem), (val), __ATOMIC_RELEASE);                        \
+ } while (0)
+
 /* XXX Is this actually correct?  */
 #define ATOMIC_EXCHANGE_USES_CAS 1
 
index 79fa4f6147c599882b79a57b9ef4806731ed2e1a..1c0325e199b464ef798a22d8524f2f3ebf6ecca8 100644 (file)
@@ -73,13 +73,18 @@ ENTRY(__clone)
 #endif
 
        /* Sanity check arguments.  */
-       comib,=,n  0, %arg0, .LerrorSanity        /* no NULL function pointers */
-       comib,=,n  0, %arg1, .LerrorSanity        /* no NULL stack pointers */
+       comib,=,n       0,%arg0,.LerrorSanity   /* no NULL function pointers */
+       comib,=,n       0,%arg1,.LerrorSanity   /* no NULL stack pointers */
+
+       /* Ensure stack argument is 8-byte aligned.  */
+       ldo             7(%r25),%r25
+       depi            0,31,3,%r25
 
        /* Save the function pointer, arg, and flags on the new stack.  */
        stwm    %r26, 64(%r25)
        stw     %r23, -60(%r25)
        stw     %r24, -56(%r25)
+
        /* Clone arguments are (int flags, void * child_stack) */
        copy    %r24, %r26              /* flags are first */
        /* User stack pointer is in the correct register already */
index 1228d0c576ef7571e3386df4732f2a792acecacb..4e6e4ba1fabcc5c0c3031b16542a398f69ce538e 100644 (file)
@@ -209,8 +209,8 @@ SYSCALL_ERROR_LABEL_DCL:                            \
 
 # define inline_syscall0(name,dummy)                                          \
   ({                                                                          \
-    register long __ret __asm__("r3");                                        \
-    register long __r12 __asm__("r12") = name;                                \
+    register long int __ret __asm__("r3");                                    \
+    register long int __r12 __asm__("r12") = name;                            \
     __asm__ __volatile__( "brki r14,8; nop;"                                  \
       : "=r"(__ret)                                                           \
       : "r"(__r12)                                                            \
@@ -219,9 +219,10 @@ SYSCALL_ERROR_LABEL_DCL:                            \
 
 # define inline_syscall1(name,arg1)                                           \
   ({                                                                          \
-    register long __ret __asm__("r3");                                        \
-    register long __r12 __asm__("r12") = name;                                \
-    register long __r5 __asm__("r5") = (long)(arg1);                          \
+    long int __arg1 = (long int) (arg1);                                      \
+    register long int __ret __asm__("r3");                                    \
+    register long int __r12 __asm__("r12") = name;                            \
+    register long int __r5 __asm__("r5") = __arg1;                            \
     __asm__ __volatile__( "brki r14,8; nop;"                                  \
       : "=r"(__ret)                                                           \
       : "r"(__r5), "r"(__r12)                                                 \
@@ -230,10 +231,12 @@ SYSCALL_ERROR_LABEL_DCL:                            \
 
 # define inline_syscall2(name,arg1,arg2)                                      \
   ({                                                                          \
-    register long __ret __asm__("r3");                                        \
-    register long __r12 __asm__("r12") = name;                                \
-    register long __r5 __asm__("r5") = (long)(arg1);                          \
-    register long __r6 __asm__("r6") = (long)(arg2);                          \
+    long int __arg1 = (long int) (arg1);                                      \
+    long int __arg2 = (long int) (arg2);                                      \
+    register long int __ret __asm__("r3");                                    \
+    register long int __r12 __asm__("r12") = name;                            \
+    register long int __r5 __asm__("r5") = __arg1;                            \
+    register long int __r6 __asm__("r6") = __arg2;                            \
     __asm__ __volatile__( "brki r14,8; nop;"                                  \
       : "=r"(__ret)                                                           \
       : "r"(__r5), "r"(__r6), "r"(__r12)                                      \
@@ -243,11 +246,14 @@ SYSCALL_ERROR_LABEL_DCL:                            \
 
 # define inline_syscall3(name,arg1,arg2,arg3)                                 \
   ({                                                                          \
-    register long __ret __asm__("r3");                                        \
-    register long __r12 __asm__("r12") = name;                                \
-    register long __r5 __asm__("r5") = (long)(arg1);                          \
-    register long __r6 __asm__("r6") = (long)(arg2);                          \
-    register long __r7 __asm__("r7") = (long)(arg3);                          \
+    long int __arg1 = (long int) (arg1);                                      \
+    long int __arg2 = (long int) (arg2);                                      \
+    long int __arg3 = (long int) (arg3);                                      \
+    register long int __ret __asm__("r3");                                    \
+    register long int __r12 __asm__("r12") = name;                            \
+    register long int __r5 __asm__("r5") = __arg1;                            \
+    register long int __r6 __asm__("r6") = __arg2;                            \
+    register long int __r7 __asm__("r7") = __arg3;                            \
     __asm__ __volatile__( "brki r14,8; nop;"                                  \
       : "=r"(__ret)                                                           \
       : "r"(__r5), "r"(__r6), "r"(__r7), "r"(__r12)                           \
@@ -257,12 +263,16 @@ SYSCALL_ERROR_LABEL_DCL:                            \
 
 # define inline_syscall4(name,arg1,arg2,arg3,arg4)                            \
   ({                                                                          \
-    register long __ret __asm__("r3");                                        \
-    register long __r12 __asm__("r12") = name;                                \
-    register long __r5 __asm__("r5") = (long)(arg1);                          \
-    register long __r6 __asm__("r6") = (long)(arg2);                          \
-    register long __r7 __asm__("r7") = (long)(arg3);                          \
-    register long __r8 __asm__("r8") = (long)(arg4);                          \
+    long int __arg1 = (long int) (arg1);                                      \
+    long int __arg2 = (long int) (arg2);                                      \
+    long int __arg3 = (long int) (arg3);                                      \
+    long int __arg4 = (long int) (arg4);                                      \
+    register long int __ret __asm__("r3");                                    \
+    register long int __r12 __asm__("r12") = name;                            \
+    register long int __r5 __asm__("r5") = __arg1;                            \
+    register long int __r6 __asm__("r6") = __arg2;                            \
+    register long int __r7 __asm__("r7") = __arg3;                            \
+    register long int __r8 __asm__("r8") = __arg4;                            \
     __asm__ __volatile__( "brki r14,8; nop;"                                  \
       : "=r"(__ret)                                                           \
       : "r"(__r5), "r"(__r6), "r"(__r7), "r"(__r8),"r"(__r12)                 \
@@ -272,13 +282,18 @@ SYSCALL_ERROR_LABEL_DCL:                            \
 
 # define inline_syscall5(name,arg1,arg2,arg3,arg4,arg5)                       \
   ({                                                                          \
-    register long __ret __asm__("r3");                                        \
-    register long __r12 __asm__("r12") = name;                                \
-    register long __r5 __asm__("r5") = (long)(arg1);                          \
-    register long __r6 __asm__("r6") = (long)(arg2);                          \
-    register long __r7 __asm__("r7") = (long)(arg3);                          \
-    register long __r8 __asm__("r8") = (long)(arg4);                          \
-    register long __r9 __asm__("r9") = (long)(arg5);                          \
+    long int __arg1 = (long int) (arg1);                                      \
+    long int __arg2 = (long int) (arg2);                                      \
+    long int __arg3 = (long int) (arg3);                                      \
+    long int __arg4 = (long int) (arg4);                                      \
+    long int __arg5 = (long int) (arg5);                                      \
+    register long int __ret __asm__("r3");                                    \
+    register long int __r12 __asm__("r12") = name;                            \
+    register long int __r5 __asm__("r5") = __arg1;                            \
+    register long int __r6 __asm__("r6") = __arg2;                            \
+    register long int __r7 __asm__("r7") = __arg3;                            \
+    register long int __r8 __asm__("r8") = __arg4;                            \
+    register long int __r9 __asm__("r9") = __arg5;                            \
     __asm__ __volatile__( "brki r14,8; nop;"                                  \
       : "=r"(__ret)                                                           \
       : "r"(__r5), "r"(__r6), "r"(__r7), "r"(__r8),"r"(__r9), "r"(__r12)      \
@@ -288,14 +303,20 @@ SYSCALL_ERROR_LABEL_DCL:                            \
 
 # define inline_syscall6(name,arg1,arg2,arg3,arg4,arg5,arg6)                  \
   ({                                                                          \
-    register long __ret __asm__("r3");                                        \
-    register long __r12 __asm__("r12") = name;                                \
-    register long __r5 __asm__("r5") = (long)(arg1);                          \
-    register long __r6 __asm__("r6") = (long)(arg2);                          \
-    register long __r7 __asm__("r7") = (long)(arg3);                          \
-    register long __r8 __asm__("r8") = (long)(arg4);                          \
-    register long __r9 __asm__("r9") = (long)(arg5);                          \
-    register long __r10 __asm__("r10") = (long)(arg6);                        \
+    long int __arg1 = (long int) (arg1);                                      \
+    long int __arg2 = (long int) (arg2);                                      \
+    long int __arg3 = (long int) (arg3);                                      \
+    long int __arg4 = (long int) (arg4);                                      \
+    long int __arg5 = (long int) (arg5);                                      \
+    long int __arg6 = (long int) (arg6);                                      \
+    register long int __ret __asm__("r3");                                    \
+    register long int __r12 __asm__("r12") = name;                            \
+    register long int __r5 __asm__("r5") = __arg1;                            \
+    register long int __r6 __asm__("r6") = __arg2;                            \
+    register long int __r7 __asm__("r7") = __arg3;                            \
+    register long int __r8 __asm__("r8") = __arg4;                            \
+    register long int __r9 __asm__("r9") = __arg5;                            \
+    register long int __r10 __asm__("r10") = __arg6;                          \
     __asm__ __volatile__( "brki r14,8; nop;"                                  \
       : "=r"(__ret)                                                           \
       : "r"(__r5), "r"(__r6), "r"(__r7), "r"(__r8),"r"(__r9), "r"(__r10),     \
index 8217f42e75e5d31641c182d0123e1fbf6da51a82..03044e73650eff5d2ff2706a8b633a02e15c64a3 100644 (file)
@@ -63,14 +63,25 @@ sysdep-dl-routines += dl-static
 
 sysdep_routines += dl-vdso
 endif
-
-# Supporting non-executable stacks on MIPS requires changes to both
-# the Linux kernel and glibc.  See
-# <https://sourceware.org/ml/libc-alpha/2016-01/msg00567.html> and
-# <https://sourceware.org/ml/libc-alpha/2016-01/msg00719.html>.
+# If the compiler doesn't use GNU.stack note,
+# this test is expected to fail.
+ifneq ($(mips-has-gnustack),yes)
 test-xfail-check-execstack = yes
 endif
+endif
 
 ifeq ($(subdir),stdlib)
 gen-as-const-headers += ucontext_i.sym
 endif
+
+ifeq ($(mips-force-execstack),yes)
+CFLAGS-.o += -Wa,-execstack
+CFLAGS-.os += -Wa,-execstack
+CFLAGS-.op += -Wa,-execstack
+CFLAGS-.oS += -Wa,-execstack
+
+ASFLAGS-.o += -Wa,-execstack
+ASFLAGS-.os += -Wa,-execstack
+ASFLAGS-.op += -Wa,-execstack
+ASFLAGS-.oS += -Wa,-execstack
+endif
index 1ee7f41a363d2e09ddfe5e207725732985478ac7..25f98e0c7b22cae74f6926033146138ca0651015 100644 (file)
@@ -475,3 +475,44 @@ if test -z "$arch_minimum_kernel"; then
     arch_minimum_kernel=4.5.0
   fi
 fi
+
+# Check if we are supposed to run on kernels older than 4.8.0. If so,
+# force executable stack to avoid potential runtime problems with fpu
+# emulation.
+# NOTE: The check below assumes that in absence of user-provided minumum_kernel
+# we will default to arch_minimum_kernel which is currently less than 4.8.0 for
+# all known configurations. If this changes, the check must be updated.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler must use executable stack" >&5
+$as_echo_n "checking whether the compiler must use executable stack... " >&6; }
+if ${libc_cv_mips_force_execstack+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  libc_cv_mips_force_execstack=no
+  if test $libc_mips_float = hard; then
+    if test -n "$minimum_kernel"; then
+
+       min_version=$((`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1 \* 65536 + \2 \* 256 + \3/'`))
+
+       if test $min_version -lt 264192; then
+         libc_cv_mips_force_execstack=yes
+       fi
+    else
+      libc_cv_mips_force_execstack=yes
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mips_force_execstack" >&5
+$as_echo "$libc_cv_mips_force_execstack" >&6; }
+
+libc_mips_has_gnustack=$libc_cv_as_noexecstack
+
+if test $libc_cv_mips_force_execstack = yes; then
+  libc_mips_has_gnustack=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: forcing executable stack for pre-4.8.0 Linux kernels" >&5
+$as_echo "$as_me: WARNING: forcing executable stack for pre-4.8.0 Linux kernels" >&2;}
+fi
+
+config_vars="$config_vars
+mips-force-execstack = ${libc_cv_mips_force_execstack}"
+config_vars="$config_vars
+mips-has-gnustack = ${libc_mips_has_gnustack}"
index 9147aa4582b987eb39777e807f82d64a0d021537..3db1b32b085083ccdd631a1b604a47f2f729f85d 100644 (file)
@@ -134,3 +134,35 @@ if test -z "$arch_minimum_kernel"; then
     arch_minimum_kernel=4.5.0
   fi
 fi
+
+# Check if we are supposed to run on kernels older than 4.8.0. If so,
+# force executable stack to avoid potential runtime problems with fpu
+# emulation.
+# NOTE: The check below assumes that in absence of user-provided minumum_kernel
+# we will default to arch_minimum_kernel which is currently less than 4.8.0 for
+# all known configurations. If this changes, the check must be updated.
+AC_CACHE_CHECK([whether the compiler must use executable stack],
+        libc_cv_mips_force_execstack, [dnl
+libc_cv_mips_force_execstack=no
+  if test $libc_mips_float = hard; then
+    if test -n "$minimum_kernel"; then
+       changequote(,)
+       min_version=$((`echo "$minimum_kernel.0.0.0" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1 \* 65536 + \2 \* 256 + \3/'`))
+       changequote([,])
+       if test $min_version -lt 264192; then
+         libc_cv_mips_force_execstack=yes
+       fi
+    else
+      libc_cv_mips_force_execstack=yes
+    fi
+  fi])
+
+libc_mips_has_gnustack=$libc_cv_as_noexecstack
+
+if test $libc_cv_mips_force_execstack = yes; then
+  libc_mips_has_gnustack=no
+  AC_MSG_WARN([forcing executable stack for pre-4.8.0 Linux kernels])
+fi
+
+LIBC_CONFIG_VAR([mips-force-execstack],[${libc_cv_mips_force_execstack}])
+LIBC_CONFIG_VAR([mips-has-gnustack],[${libc_mips_has_gnustack}])
index 649881f8b1a2425c0f7fe037bf1f107109616116..c0729252a908ffb6a2e967ad76e2359c64d78fcd 100644 (file)
@@ -22,9 +22,9 @@
        .text
        .set    nomips16
 
-/* long long __mips_syscall5 (long arg1, long arg2, long arg3, long arg4,
-                             long arg5,
-                             long number)  */
+/* long long int __mips_syscall5 (long int arg1, long int arg2, long int arg3,
+                                 long int arg4, long int arg5,
+                                 long int number)  */
 
 ENTRY(__mips_syscall5)
        lw      v0, 20(sp)
index 2c954f8e770b1cf0bf2e60724d8edf42c048cf07..e4c95fb1e4f9c72525fd52cecefd0a4f33c760e3 100644 (file)
@@ -22,9 +22,9 @@
        .text
        .set    nomips16
 
-/* long long __mips_syscall6 (long arg1, long arg2, long arg3, long arg4,
-                             long arg5, long arg6,
-                             long number)  */
+/* long long int __mips_syscall6 (long int arg1, long int arg2, long int arg3,
+                                 long int arg4, long int arg5, long int arg6,
+                                 long int number)  */
 
 ENTRY(__mips_syscall6)
        lw      v0, 24(sp)
index fb6c9c5e0f7e626d328f1f3df606c37efdb2b52d..489fab989ce8106aa7f50efa148704d9be37d595 100644 (file)
        .text
        .set    nomips16
 
-/* long long __mips_syscall7 (long arg1, long arg2, long arg3, long arg4,
-                             long arg5, long arg6, long arg7,
-                             long number)  */
+/* long long int __mips_syscall7 (long int arg1, long int arg2, long int arg3,
+                                 long int arg4, long int arg5, long int arg6,
+                                 long int arg7,
+                                 long int number)  */
 
 ENTRY(__mips_syscall7)
        lw      v0, 28(sp)
index 4f917c5d3453ef0abd2f3150199ec91cd8afa644..faa5ac68a381e675f7e28892a7cb0f8ecf93f112 100644 (file)
 #ifndef MIPS16_SYSCALL_H
 #define MIPS16_SYSCALL_H 1
 
-long long __nomips16 __mips16_syscall0 (long number);
+long long int __nomips16 __mips16_syscall0 (long int number);
 #define __mips16_syscall0(dummy, number)                               \
-       __mips16_syscall0 ((long) (number))
+       __mips16_syscall0 ((long int) (number))
 
-long long __nomips16 __mips16_syscall1 (long a0,
-                                       long number);
+long long int __nomips16 __mips16_syscall1 (long int a0,
+                                           long int number);
 #define __mips16_syscall1(a0, number)                                  \
-       __mips16_syscall1 ((long) (a0),                                 \
-                          (long) (number))
+       __mips16_syscall1 ((long int) (a0),                             \
+                          (long int) (number))
 
-long long __nomips16 __mips16_syscall2 (long a0, long a1,
-                                       long number);
+long long int __nomips16 __mips16_syscall2 (long int a0, long int a1,
+                                           long int number);
 #define __mips16_syscall2(a0, a1, number)                              \
-       __mips16_syscall2 ((long) (a0), (long) (a1),                    \
-                          (long) (number))
+       __mips16_syscall2 ((long int) (a0), (long int) (a1),            \
+                          (long int) (number))
 
-long long __nomips16 __mips16_syscall3 (long a0, long a1, long a2,
-                                       long number);
+long long int __nomips16 __mips16_syscall3 (long int a0, long int a1,
+                                           long int a2,
+                                           long int number);
 #define __mips16_syscall3(a0, a1, a2, number)                          \
-       __mips16_syscall3 ((long) (a0), (long) (a1), (long) (a2),       \
-                          (long) (number))
+       __mips16_syscall3 ((long int) (a0), (long int) (a1),            \
+                          (long int) (a2),                             \
+                          (long int) (number))
 
-long long __nomips16 __mips16_syscall4 (long a0, long a1, long a2, long a3,
-                                       long number);
+long long int __nomips16 __mips16_syscall4 (long int a0, long int a1,
+                                           long int a2, long int a3,
+                                           long int number);
 #define __mips16_syscall4(a0, a1, a2, a3, number)                      \
-       __mips16_syscall4 ((long) (a0), (long) (a1), (long) (a2),       \
-                          (long) (a3),                                 \
-                          (long) (number))
+       __mips16_syscall4 ((long int) (a0), (long int) (a1),            \
+                          (long int) (a2), (long int) (a3),            \
+                          (long int) (number))
 
 /* The remaining ones use regular MIPS wrappers.  */
 
 #define __mips16_syscall5(a0, a1, a2, a3, a4, number)                  \
-       __mips_syscall5 ((long) (a0), (long) (a1), (long) (a2),         \
-                        (long) (a3), (long) (a4),                      \
-                        (long) (number))
+       __mips_syscall5 ((long int) (a0), (long int) (a1),              \
+                        (long int) (a2), (long int) (a3),              \
+                        (long int) (a4),                               \
+                        (long int) (number))
 
 #define __mips16_syscall6(a0, a1, a2, a3, a4, a5, number)              \
-       __mips_syscall6 ((long) (a0), (long) (a1), (long) (a2),         \
-                        (long) (a3), (long) (a4), (long) (a5),         \
-                        (long) (number))
+       __mips_syscall6 ((long int) (a0), (long int) (a1),              \
+                        (long int) (a2), (long int) (a3),              \
+                        (long int) (a4), (long int) (a5),              \
+                        (long int) (number))
 
 #define __mips16_syscall7(a0, a1, a2, a3, a4, a5, a6, number)          \
-       __mips_syscall7 ((long) (a0), (long) (a1), (long) (a2),         \
-                        (long) (a3), (long) (a4), (long) (a5),         \
-                        (long) (a6),                                   \
-                        (long) (number))
+       __mips_syscall7 ((long int) (a0), (long int) (a1),              \
+                        (long int) (a2), (long int) (a3),              \
+                        (long int) (a4), (long int) (a5),              \
+                        (long int) (a6),                               \
+                        (long int) (number))
 
 #endif
index c8f6fff40d8c1156d864d974b377ed63b9fa05fe..28b48d99b846de528d3d110babe0726b7d827cae 100644 (file)
@@ -20,8 +20,8 @@
 
 #undef __mips16_syscall0
 
-long long __nomips16
-__mips16_syscall0 (long number)
+long long int __nomips16
+__mips16_syscall0 (long int number)
 {
   union __mips_syscall_return ret;
   ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 0);
index 2631ec25aa284c3f3021bfa97077b762d127fbe2..0e7ef00a8fada1c7b30db2792486af224c61759b 100644 (file)
@@ -20,9 +20,9 @@
 
 #undef __mips16_syscall1
 
-long long __nomips16
-__mips16_syscall1 (long a0,
-                  long number)
+long long int __nomips16
+__mips16_syscall1 (long int a0,
+                  long int number)
 {
   union __mips_syscall_return ret;
   ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 1,
index 235958e3555d4139eec6f980b1b3fca0fb725258..7464b88d71ceddb403acb56883054e72d1acf906 100644 (file)
@@ -20,9 +20,9 @@
 
 #undef __mips16_syscall2
 
-long long __nomips16
-__mips16_syscall2 (long a0, long a1,
-                  long number)
+long long int __nomips16
+__mips16_syscall2 (long int a0, long int a1,
+                  long int number)
 {
   union __mips_syscall_return ret;
   ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 2,
index 827c5e23a52dda3908a2129b2d52790face2f95f..38d48208e0d3ddd6e328844fbe7ceb49375aa341 100644 (file)
@@ -20,9 +20,9 @@
 
 #undef __mips16_syscall3
 
-long long __nomips16
-__mips16_syscall3 (long a0, long a1, long a2,
-                  long number)
+long long int __nomips16
+__mips16_syscall3 (long int a0, long int a1, long int a2,
+                  long int number)
 {
   union __mips_syscall_return ret;
   ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 3,
index 3eb040056ad3dd0b33f1b69623a6d84f5f02df86..5027b5ae1887d0f1ca484a1f9ebab30b8dec8ded 100644 (file)
@@ -20,9 +20,9 @@
 
 #undef __mips16_syscall4
 
-long long __nomips16
-__mips16_syscall4 (long a0, long a1, long a2, long a3,
-                  long number)
+long long int __nomips16
+__mips16_syscall4 (long int a0, long int a1, long int a2, long int a3,
+                  long int number)
 {
   union __mips_syscall_return ret;
   ret.reg.v0 = INTERNAL_SYSCALL_MIPS16 (number, ret.reg.v1, 4,
index 5a2704e3e8df1f259a0356e56da65452b867b4b1..4384bf50eeffe9b595d9069cbd38288510e96fd4 100644 (file)
@@ -54,7 +54,7 @@
 #undef INLINE_SYSCALL
 #define INLINE_SYSCALL(name, nr, args...)                               \
   ({ INTERNAL_SYSCALL_DECL (_sc_err);                                  \
-     long result_var = INTERNAL_SYSCALL (name, _sc_err, nr, args);     \
+     long int result_var = INTERNAL_SYSCALL (name, _sc_err, nr, args); \
      if ( INTERNAL_SYSCALL_ERROR_P (result_var, _sc_err) )             \
        {                                                               \
         __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, _sc_err));    \
      result_var; })
 
 #undef INTERNAL_SYSCALL_DECL
-#define INTERNAL_SYSCALL_DECL(err) long err __attribute__ ((unused))
+#define INTERNAL_SYSCALL_DECL(err) long int err __attribute__ ((unused))
 
 #undef INTERNAL_SYSCALL_ERROR_P
-#define INTERNAL_SYSCALL_ERROR_P(val, err)   ((void) (val), (long) (err))
+#define INTERNAL_SYSCALL_ERROR_P(val, err)   ((void) (val), (long int) (err))
 
 #undef INTERNAL_SYSCALL_ERRNO
 #define INTERNAL_SYSCALL_ERRNO(val, err)     ((void) (err), val)
 
 union __mips_syscall_return
   {
-    long long val;
+    long long int val;
     struct
       {
-       long v0;
-       long v1;
+       long int v0;
+       long int v1;
       }
     reg;
   };
@@ -154,13 +154,13 @@ union __mips_syscall_return
 
 #define internal_syscall0(v0_init, input, number, err, dummy...)       \
 ({                                                                     \
-       long _sys_result;                                               \
+       long int _sys_result;                                           \
                                                                        \
        {                                                               \
-       register long __s0 asm ("$16") __attribute__ ((unused))         \
+       register long int __s0 asm ("$16") __attribute__ ((unused))     \
          = (number);                                                   \
-       register long __v0 asm ("$2");                                  \
-       register long __a3 asm ("$7");                                  \
+       register long int __v0 asm ("$2");                              \
+       register long int __a3 asm ("$7");                              \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
        v0_init                                                         \
@@ -177,14 +177,15 @@ union __mips_syscall_return
 
 #define internal_syscall1(v0_init, input, number, err, arg1)           \
 ({                                                                     \
-       long _sys_result;                                               \
+       long int _sys_result;                                           \
                                                                        \
        {                                                               \
-       register long __s0 asm ("$16") __attribute__ ((unused))         \
+       long int _arg1 = (long int) (arg1);                             \
+       register long int __s0 asm ("$16") __attribute__ ((unused))     \
          = (number);                                                   \
-       register long __v0 asm ("$2");                                  \
-       register long __a0 asm ("$4") = (long) (arg1);                  \
-       register long __a3 asm ("$7");                                  \
+       register long int __v0 asm ("$2");                              \
+       register long int __a0 asm ("$4") = _arg1;                      \
+       register long int __a3 asm ("$7");                              \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
        v0_init                                                         \
@@ -201,15 +202,17 @@ union __mips_syscall_return
 
 #define internal_syscall2(v0_init, input, number, err, arg1, arg2)     \
 ({                                                                     \
-       long _sys_result;                                               \
+       long int _sys_result;                                           \
                                                                        \
        {                                                               \
-       register long __s0 asm ("$16") __attribute__ ((unused))         \
+       long int _arg1 = (long int) (arg1);                             \
+       long int _arg2 = (long int) (arg2);                             \
+       register long int __s0 asm ("$16") __attribute__ ((unused))     \
          = (number);                                                   \
-       register long __v0 asm ("$2");                                  \
-       register long __a0 asm ("$4") = (long) (arg1);                  \
-       register long __a1 asm ("$5") = (long) (arg2);                  \
-       register long __a3 asm ("$7");                                  \
+       register long int __v0 asm ("$2");                              \
+       register long int __a0 asm ("$4") = _arg1;                      \
+       register long int __a1 asm ("$5") = _arg2;                      \
+       register long int __a3 asm ("$7");                              \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
        v0_init                                                         \
@@ -227,16 +230,19 @@ union __mips_syscall_return
 #define internal_syscall3(v0_init, input, number, err,                 \
                          arg1, arg2, arg3)                             \
 ({                                                                     \
-       long _sys_result;                                               \
+       long int _sys_result;                                           \
                                                                        \
        {                                                               \
-       register long __s0 asm ("$16") __attribute__ ((unused))         \
+       long int _arg1 = (long int) (arg1);                             \
+       long int _arg2 = (long int) (arg2);                             \
+       long int _arg3 = (long int) (arg3);                             \
+       register long int __s0 asm ("$16") __attribute__ ((unused))     \
          = (number);                                                   \
-       register long __v0 asm ("$2");                                  \
-       register long __a0 asm ("$4") = (long) (arg1);                  \
-       register long __a1 asm ("$5") = (long) (arg2);                  \
-       register long __a2 asm ("$6") = (long) (arg3);                  \
-       register long __a3 asm ("$7");                                  \
+       register long int __v0 asm ("$2");                              \
+       register long int __a0 asm ("$4") = _arg1;                      \
+       register long int __a1 asm ("$5") = _arg2;                      \
+       register long int __a2 asm ("$6") = _arg3;                      \
+       register long int __a3 asm ("$7");                              \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
        v0_init                                                         \
@@ -254,16 +260,20 @@ union __mips_syscall_return
 #define internal_syscall4(v0_init, input, number, err,                 \
                          arg1, arg2, arg3, arg4)                       \
 ({                                                                     \
-       long _sys_result;                                               \
+       long int _sys_result;                                           \
                                                                        \
        {                                                               \
-       register long __s0 asm ("$16") __attribute__ ((unused))         \
+       long int _arg1 = (long int) (arg1);                             \
+       long int _arg2 = (long int) (arg2);                             \
+       long int _arg3 = (long int) (arg3);                             \
+       long int _arg4 = (long int) (arg4);                             \
+       register long int __s0 asm ("$16") __attribute__ ((unused))     \
          = (number);                                                   \
-       register long __v0 asm ("$2");                                  \
-       register long __a0 asm ("$4") = (long) (arg1);                  \
-       register long __a1 asm ("$5") = (long) (arg2);                  \
-       register long __a2 asm ("$6") = (long) (arg3);                  \
-       register long __a3 asm ("$7") = (long) (arg4);                  \
+       register long int __v0 asm ("$2");                              \
+       register long int __a0 asm ("$4") = _arg1;                      \
+       register long int __a1 asm ("$5") = _arg2;                      \
+       register long int __a2 asm ("$6") = _arg3;                      \
+       register long int __a3 asm ("$7") = _arg4;                      \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
        v0_init                                                         \
@@ -287,63 +297,66 @@ union __mips_syscall_return
    compiler specifics required for the stack arguments to be pushed,
    which would be the case if these syscalls were inlined.  */
 
-long long __nomips16 __mips_syscall5 (long arg1, long arg2, long arg3,
-                                     long arg4, long arg5,
-                                     long number);
+long long int __nomips16 __mips_syscall5 (long int arg1, long int arg2,
+                                         long int arg3, long int arg4,
+                                         long int arg5,
+                                         long int number);
 libc_hidden_proto (__mips_syscall5, nomips16)
 
 #define internal_syscall5(v0_init, input, number, err,                 \
                          arg1, arg2, arg3, arg4, arg5)                 \
 ({                                                                     \
        union __mips_syscall_return _sc_ret;                            \
-       _sc_ret.val = __mips_syscall5 ((long) (arg1),                   \
-                                      (long) (arg2),                   \
-                                      (long) (arg3),                   \
-                                      (long) (arg4),                   \
-                                      (long) (arg5),                   \
-                                      (long) (number));                \
+       _sc_ret.val = __mips_syscall5 ((long int) (arg1),               \
+                                      (long int) (arg2),               \
+                                      (long int) (arg3),               \
+                                      (long int) (arg4),               \
+                                      (long int) (arg5),               \
+                                      (long int) (number));            \
        err = _sc_ret.reg.v1;                                           \
        _sc_ret.reg.v0;                                                 \
 })
 
-long long __nomips16 __mips_syscall6 (long arg1, long arg2, long arg3,
-                                     long arg4, long arg5, long arg6,
-                                     long number);
+long long int __nomips16 __mips_syscall6 (long int arg1, long int arg2,
+                                         long int arg3, long int arg4,
+                                         long int arg5, long int arg6,
+                                         long int number);
 libc_hidden_proto (__mips_syscall6, nomips16)
 
 #define internal_syscall6(v0_init, input, number, err,                 \
                          arg1, arg2, arg3, arg4, arg5, arg6)           \
 ({                                                                     \
        union __mips_syscall_return _sc_ret;                            \
-       _sc_ret.val = __mips_syscall6 ((long) (arg1),                   \
-                                      (long) (arg2),                   \
-                                      (long) (arg3),                   \
-                                      (long) (arg4),                   \
-                                      (long) (arg5),                   \
-                                      (long) (arg6),                   \
-                                      (long) (number));                \
+       _sc_ret.val = __mips_syscall6 ((long int) (arg1),               \
+                                      (long int) (arg2),               \
+                                      (long int) (arg3),               \
+                                      (long int) (arg4),               \
+                                      (long int) (arg5),               \
+                                      (long int) (arg6),               \
+                                      (long int) (number));            \
        err = _sc_ret.reg.v1;                                           \
        _sc_ret.reg.v0;                                                 \
 })
 
-long long __nomips16 __mips_syscall7 (long arg1, long arg2, long arg3,
-                                     long arg4, long arg5, long arg6,
-                                     long arg7,
-                                     long number);
+long long int __nomips16 __mips_syscall7 (long int arg1, long int arg2,
+                                         long int arg3, long int arg4,
+                                         long int arg5, long int arg6,
+                                         long int arg7,
+                                         long int number);
 libc_hidden_proto (__mips_syscall7, nomips16)
 
 #define internal_syscall7(v0_init, input, number, err,                 \
                          arg1, arg2, arg3, arg4, arg5, arg6, arg7)     \
 ({                                                                     \
        union __mips_syscall_return _sc_ret;                            \
-       _sc_ret.val = __mips_syscall7 ((long) (arg1),                   \
-                                      (long) (arg2),                   \
-                                      (long) (arg3),                   \
-                                      (long) (arg4),                   \
-                                      (long) (arg5),                   \
-                                      (long) (arg6),                   \
-                                      (long) (arg7),                   \
-                                      (long) (number));                \
+       _sc_ret.val = __mips_syscall7 ((long int) (arg1),               \
+                                      (long int) (arg2),               \
+                                      (long int) (arg3),               \
+                                      (long int) (arg4),               \
+                                      (long int) (arg5),               \
+                                      (long int) (arg6),               \
+                                      (long int) (arg7),               \
+                                      (long int) (number));            \
        err = _sc_ret.reg.v1;                                           \
        _sc_ret.reg.v0;                                                 \
 })
@@ -357,7 +370,7 @@ libc_hidden_proto (__mips_syscall7, nomips16)
 #define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...)              \
   ({                                                                   \
     long _ret = funcptr (args);                                                \
-    err = ((unsigned long) (_ret) >= (unsigned long) -4095L);          \
+    err = ((unsigned long) (_ret) >= (unsigned long int) -4095L);      \
     if (err)                                                           \
       _ret = -_ret;                                                    \
     _ret;                                                              \
index a4f35470309e34b5c55add9e55a1a747a3923b71..e0251d551471b7a5bcc93368a3879b509e767829 100644 (file)
 
 /* Convert X to a long long, without losing any bits if it is one
    already or warning if it is a 32-bit pointer.  */
-#define ARGIFY(X) ((long long) (__typeof__ ((X) - (X))) (X))
+#define ARGIFY(X) ((long long int) (__typeof__ ((X) - (X))) (X))
 
 /* Define a macro which expands into the inline wrapper code for a system
    call.  */
 #undef INLINE_SYSCALL
 #define INLINE_SYSCALL(name, nr, args...)                              \
   ({ INTERNAL_SYSCALL_DECL (_sc_err);                                  \
-     long result_var = INTERNAL_SYSCALL (name, _sc_err, nr, args);     \
+     long int result_var = INTERNAL_SYSCALL (name, _sc_err, nr, args); \
      if ( INTERNAL_SYSCALL_ERROR_P (result_var, _sc_err) )             \
        {                                                               \
         __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, _sc_err));    \
      result_var; })
 
 #undef INTERNAL_SYSCALL_DECL
-#define INTERNAL_SYSCALL_DECL(err) long err __attribute__ ((unused))
+#define INTERNAL_SYSCALL_DECL(err) long int err __attribute__ ((unused))
 
 #undef INTERNAL_SYSCALL_ERROR_P
-#define INTERNAL_SYSCALL_ERROR_P(val, err)   ((void) (val), (long) (err))
+#define INTERNAL_SYSCALL_ERROR_P(val, err)   ((void) (val), (long int) (err))
 
 #undef INTERNAL_SYSCALL_ERRNO
 #define INTERNAL_SYSCALL_ERRNO(val, err)     ((void) (err), val)
 
 #define internal_syscall0(v0_init, input, number, err, dummy...)       \
 ({                                                                     \
-       long _sys_result;                                               \
+       long int _sys_result;                                           \
                                                                        \
        {                                                               \
-       register long long __s0 asm ("$16") __attribute__ ((unused))    \
+       register long long int __s0 asm ("$16") __attribute__ ((unused))\
          = (number);                                                   \
-       register long long __v0 asm ("$2");                             \
-       register long long __a3 asm ("$7");                             \
+       register long long int __v0 asm ("$2");                         \
+       register long long int __a3 asm ("$7");                         \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
        v0_init                                                         \
 
 #define internal_syscall1(v0_init, input, number, err, arg1)           \
 ({                                                                     \
-       long _sys_result;                                               \
+       long int _sys_result;                                           \
                                                                        \
        {                                                               \
-       register long long __s0 asm ("$16") __attribute__ ((unused))    \
+       long long int _arg1 = ARGIFY (arg1);                            \
+       register long long int __s0 asm ("$16") __attribute__ ((unused))\
          = (number);                                                   \
-       register long long __v0 asm ("$2");                             \
-       register long long __a0 asm ("$4") = ARGIFY (arg1);             \
-       register long long __a3 asm ("$7");                             \
+       register long long int __v0 asm ("$2");                         \
+       register long long int __a0 asm ("$4") = _arg1;                 \
+       register long long int __a3 asm ("$7");                         \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
        v0_init                                                         \
 
 #define internal_syscall2(v0_init, input, number, err, arg1, arg2)     \
 ({                                                                     \
-       long _sys_result;                                               \
+       long int _sys_result;                                           \
                                                                        \
        {                                                               \
-       register long long __s0 asm ("$16") __attribute__ ((unused))    \
+       long long int _arg1 = ARGIFY (arg1);                            \
+       long long int _arg2 = ARGIFY (arg2);                            \
+       register long long int __s0 asm ("$16") __attribute__ ((unused))\
          = (number);                                                   \
-       register long long __v0 asm ("$2");                             \
-       register long long __a0 asm ("$4") = ARGIFY (arg1);             \
-       register long long __a1 asm ("$5") = ARGIFY (arg2);             \
-       register long long __a3 asm ("$7");                             \
+       register long long int __v0 asm ("$2");                         \
+       register long long int __a0 asm ("$4") = _arg1;                 \
+       register long long int __a1 asm ("$5") = _arg2;                 \
+       register long long int __a3 asm ("$7");                         \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
        v0_init                                                         \
 #define internal_syscall3(v0_init, input, number, err,                 \
                          arg1, arg2, arg3)                             \
 ({                                                                     \
-       long _sys_result;                                               \
+       long int _sys_result;                                           \
                                                                        \
        {                                                               \
-       register long long __s0 asm ("$16") __attribute__ ((unused))    \
+       long long int _arg1 = ARGIFY (arg1);                            \
+       long long int _arg2 = ARGIFY (arg2);                            \
+       long long int _arg3 = ARGIFY (arg3);                            \
+       register long long int __s0 asm ("$16") __attribute__ ((unused))\
          = (number);                                                   \
-       register long long __v0 asm ("$2");                             \
-       register long long __a0 asm ("$4") = ARGIFY (arg1);             \
-       register long long __a1 asm ("$5") = ARGIFY (arg2);             \
-       register long long __a2 asm ("$6") = ARGIFY (arg3);             \
-       register long long __a3 asm ("$7");                             \
+       register long long int __v0 asm ("$2");                         \
+       register long long int __a0 asm ("$4") = _arg1;                 \
+       register long long int __a1 asm ("$5") = _arg2;                 \
+       register long long int __a2 asm ("$6") = _arg3;                 \
+       register long long int __a3 asm ("$7");                         \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
        v0_init                                                         \
 #define internal_syscall4(v0_init, input, number, err,                 \
                          arg1, arg2, arg3, arg4)                       \
 ({                                                                     \
-       long _sys_result;                                               \
+       long int _sys_result;                                           \
                                                                        \
        {                                                               \
-       register long long __s0 asm ("$16") __attribute__ ((unused))    \
+       long long int _arg1 = ARGIFY (arg1);                            \
+       long long int _arg2 = ARGIFY (arg2);                            \
+       long long int _arg3 = ARGIFY (arg3);                            \
+       long long int _arg4 = ARGIFY (arg4);                            \
+       register long long int __s0 asm ("$16") __attribute__ ((unused))\
          = (number);                                                   \
-       register long long __v0 asm ("$2");                             \
-       register long long __a0 asm ("$4") = ARGIFY (arg1);             \
-       register long long __a1 asm ("$5") = ARGIFY (arg2);             \
-       register long long __a2 asm ("$6") = ARGIFY (arg3);             \
-       register long long __a3 asm ("$7") = ARGIFY (arg4);             \
+       register long long int __v0 asm ("$2");                         \
+       register long long int __a0 asm ("$4") = _arg1;                 \
+       register long long int __a1 asm ("$5") = _arg2;                 \
+       register long long int __a2 asm ("$6") = _arg3;                 \
+       register long long int __a3 asm ("$7") = _arg4;                 \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
        v0_init                                                         \
 #define internal_syscall5(v0_init, input, number, err,                 \
                          arg1, arg2, arg3, arg4, arg5)                 \
 ({                                                                     \
-       long _sys_result;                                               \
+       long int _sys_result;                                           \
                                                                        \
        {                                                               \
-       register long long __s0 asm ("$16") __attribute__ ((unused))    \
+       long long int _arg1 = ARGIFY (arg1);                            \
+       long long int _arg2 = ARGIFY (arg2);                            \
+       long long int _arg3 = ARGIFY (arg3);                            \
+       long long int _arg4 = ARGIFY (arg4);                            \
+       long long int _arg5 = ARGIFY (arg5);                            \
+       register long long int __s0 asm ("$16") __attribute__ ((unused))\
          = (number);                                                   \
-       register long long __v0 asm ("$2");                             \
-       register long long __a0 asm ("$4") = ARGIFY (arg1);             \
-       register long long __a1 asm ("$5") = ARGIFY (arg2);             \
-       register long long __a2 asm ("$6") = ARGIFY (arg3);             \
-       register long long __a3 asm ("$7") = ARGIFY (arg4);             \
-       register long long __a4 asm ("$8") = ARGIFY (arg5);             \
+       register long long int __v0 asm ("$2");                         \
+       register long long int __a0 asm ("$4") = _arg1;                 \
+       register long long int __a1 asm ("$5") = _arg2;                 \
+       register long long int __a2 asm ("$6") = _arg3;                 \
+       register long long int __a3 asm ("$7") = _arg4;                 \
+       register long long int __a4 asm ("$8") = _arg5;                 \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
        v0_init                                                         \
 #define internal_syscall6(v0_init, input, number, err,                 \
                          arg1, arg2, arg3, arg4, arg5, arg6)           \
 ({                                                                     \
-       long _sys_result;                                               \
+       long int _sys_result;                                           \
                                                                        \
        {                                                               \
-       register long long __s0 asm ("$16") __attribute__ ((unused))    \
+       long long int _arg1 = ARGIFY (arg1);                            \
+       long long int _arg2 = ARGIFY (arg2);                            \
+       long long int _arg3 = ARGIFY (arg3);                            \
+       long long int _arg4 = ARGIFY (arg4);                            \
+       long long int _arg5 = ARGIFY (arg5);                            \
+       long long int _arg6 = ARGIFY (arg6);                            \
+       register long long int __s0 asm ("$16") __attribute__ ((unused))\
          = (number);                                                   \
-       register long long __v0 asm ("$2");                             \
-       register long long __a0 asm ("$4") = ARGIFY (arg1);             \
-       register long long __a1 asm ("$5") = ARGIFY (arg2);             \
-       register long long __a2 asm ("$6") = ARGIFY (arg3);             \
-       register long long __a3 asm ("$7") = ARGIFY (arg4);             \
-       register long long __a4 asm ("$8") = ARGIFY (arg5);             \
-       register long long __a5 asm ("$9") = ARGIFY (arg6);             \
+       register long long int __v0 asm ("$2");                         \
+       register long long int __a0 asm ("$4") = _arg1;                 \
+       register long long int __a1 asm ("$5") = _arg2;                 \
+       register long long int __a2 asm ("$6") = _arg3;                 \
+       register long long int __a3 asm ("$7") = _arg4;                 \
+       register long long int __a4 asm ("$8") = _arg5;                 \
+       register long long int __a5 asm ("$9") = _arg6;                 \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
        v0_init                                                         \
 #define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...)              \
   ({                                                                   \
     long _ret = funcptr (args);                                                \
-    err = ((unsigned long) (_ret) >= (unsigned long) -4095L);          \
+    err = ((unsigned long) (_ret) >= (unsigned long int) -4095L);      \
     if (err)                                                           \
       _ret = -_ret;                                                    \
     _ret;                                                              \
index 5b4d27757dad00493484fb28c531fe11ba819f97..11172280c7699ad6b567540f7f926d81ab2019de 100644 (file)
@@ -52,7 +52,7 @@
 #undef INLINE_SYSCALL
 #define INLINE_SYSCALL(name, nr, args...)                              \
   ({ INTERNAL_SYSCALL_DECL (_sc_err);                                  \
-     long result_var = INTERNAL_SYSCALL (name, _sc_err, nr, args);     \
+     long int result_var = INTERNAL_SYSCALL (name, _sc_err, nr, args); \
      if ( INTERNAL_SYSCALL_ERROR_P (result_var, _sc_err) )             \
        {                                                               \
         __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, _sc_err));    \
      result_var; })
 
 #undef INTERNAL_SYSCALL_DECL
-#define INTERNAL_SYSCALL_DECL(err) long err __attribute__ ((unused))
+#define INTERNAL_SYSCALL_DECL(err) long int err __attribute__ ((unused))
 
 #undef INTERNAL_SYSCALL_ERROR_P
-#define INTERNAL_SYSCALL_ERROR_P(val, err)   ((void) (val), (long) (err))
+#define INTERNAL_SYSCALL_ERROR_P(val, err)   ((void) (val), (long int) (err))
 
 #undef INTERNAL_SYSCALL_ERRNO
 #define INTERNAL_SYSCALL_ERRNO(val, err)     ((void) (err), val)
 
 #define internal_syscall0(v0_init, input, number, err, dummy...)       \
 ({                                                                     \
-       long _sys_result;                                               \
+       long int _sys_result;                                           \
                                                                        \
        {                                                               \
-       register long __s0 asm ("$16") __attribute__ ((unused))         \
+       register long int __s0 asm ("$16") __attribute__ ((unused))     \
          = (number);                                                   \
-       register long __v0 asm ("$2");                                  \
-       register long __a3 asm ("$7");                                  \
+       register long int __v0 asm ("$2");                              \
+       register long int __a3 asm ("$7");                              \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
        v0_init                                                         \
 
 #define internal_syscall1(v0_init, input, number, err, arg1)           \
 ({                                                                     \
-       long _sys_result;                                               \
+       long int _sys_result;                                           \
                                                                        \
        {                                                               \
-       register long __s0 asm ("$16") __attribute__ ((unused))         \
+       long int _arg1 = (long int) (arg1);                             \
+       register long int __s0 asm ("$16") __attribute__ ((unused))     \
          = (number);                                                   \
-       register long __v0 asm ("$2");                                  \
-       register long __a0 asm ("$4") = (long) (arg1);                  \
-       register long __a3 asm ("$7");                                  \
+       register long int __v0 asm ("$2");                              \
+       register long int __a0 asm ("$4") = _arg1;                      \
+       register long int __a3 asm ("$7");                              \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
        v0_init                                                         \
 
 #define internal_syscall2(v0_init, input, number, err, arg1, arg2)     \
 ({                                                                     \
-       long _sys_result;                                               \
+       long int _sys_result;                                           \
                                                                        \
        {                                                               \
-       register long __s0 asm ("$16") __attribute__ ((unused))         \
+       long int _arg1 = (long int) (arg1);                             \
+       long int _arg2 = (long int) (arg2);                             \
+       register long int __s0 asm ("$16") __attribute__ ((unused))     \
          = (number);                                                   \
-       register long __v0 asm ("$2");                                  \
-       register long __a0 asm ("$4") = (long) (arg1);                  \
-       register long __a1 asm ("$5") = (long) (arg2);                  \
-       register long __a3 asm ("$7");                                  \
+       register long int __v0 asm ("$2");                              \
+       register long int __a0 asm ("$4") = _arg1;                      \
+       register long int __a1 asm ("$5") = _arg2;                      \
+       register long int __a3 asm ("$7");                              \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
        v0_init                                                         \
 #define internal_syscall3(v0_init, input, number, err,                 \
                          arg1, arg2, arg3)                             \
 ({                                                                     \
-       long _sys_result;                                               \
+       long int _sys_result;                                           \
                                                                        \
        {                                                               \
-       register long __s0 asm ("$16") __attribute__ ((unused))         \
+       long int _arg1 = (long int) (arg1);                             \
+       long int _arg2 = (long int) (arg2);                             \
+       long int _arg3 = (long int) (arg3);                             \
+       register long int __s0 asm ("$16") __attribute__ ((unused))     \
          = (number);                                                   \
-       register long __v0 asm ("$2");                                  \
-       register long __a0 asm ("$4") = (long) (arg1);                  \
-       register long __a1 asm ("$5") = (long) (arg2);                  \
-       register long __a2 asm ("$6") = (long) (arg3);                  \
-       register long __a3 asm ("$7");                                  \
+       register long int __v0 asm ("$2");                              \
+       register long int __a0 asm ("$4") = _arg1;                      \
+       register long int __a1 asm ("$5") = _arg2;                      \
+       register long int __a2 asm ("$6") = _arg3;                      \
+       register long int __a3 asm ("$7");                              \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
        v0_init                                                         \
 #define internal_syscall4(v0_init, input, number, err,                 \
                          arg1, arg2, arg3, arg4)                       \
 ({                                                                     \
-       long _sys_result;                                               \
+       long int _sys_result;                                           \
                                                                        \
        {                                                               \
-       register long __s0 asm ("$16") __attribute__ ((unused))         \
+       long int _arg1 = (long int) (arg1);                             \
+       long int _arg2 = (long int) (arg2);                             \
+       long int _arg3 = (long int) (arg3);                             \
+       long int _arg4 = (long int) (arg4);                             \
+       register long int __s0 asm ("$16") __attribute__ ((unused))     \
          = (number);                                                   \
-       register long __v0 asm ("$2");                                  \
-       register long __a0 asm ("$4") = (long) (arg1);                  \
-       register long __a1 asm ("$5") = (long) (arg2);                  \
-       register long __a2 asm ("$6") = (long) (arg3);                  \
-       register long __a3 asm ("$7") = (long) (arg4);                  \
+       register long int __v0 asm ("$2");                              \
+       register long int __a0 asm ("$4") = _arg1;                      \
+       register long int __a1 asm ("$5") = _arg2;                      \
+       register long int __a2 asm ("$6") = _arg3;                      \
+       register long int __a3 asm ("$7") = _arg4;                      \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
        v0_init                                                         \
 #define internal_syscall5(v0_init, input, number, err,                 \
                          arg1, arg2, arg3, arg4, arg5)                 \
 ({                                                                     \
-       long _sys_result;                                               \
+       long int _sys_result;                                           \
                                                                        \
        {                                                               \
-       register long __s0 asm ("$16") __attribute__ ((unused))         \
+       long int _arg1 = (long int) (arg1);                             \
+       long int _arg2 = (long int) (arg2);                             \
+       long int _arg3 = (long int) (arg3);                             \
+       long int _arg4 = (long int) (arg4);                             \
+       long int _arg5 = (long int) (arg5);                             \
+       register long int __s0 asm ("$16") __attribute__ ((unused))     \
          = (number);                                                   \
-       register long __v0 asm ("$2");                                  \
-       register long __a0 asm ("$4") = (long) (arg1);                  \
-       register long __a1 asm ("$5") = (long) (arg2);                  \
-       register long __a2 asm ("$6") = (long) (arg3);                  \
-       register long __a3 asm ("$7") = (long) (arg4);                  \
-       register long __a4 asm ("$8") = (long) (arg5);                  \
+       register long int __v0 asm ("$2");                              \
+       register long int __a0 asm ("$4") = _arg1;                      \
+       register long int __a1 asm ("$5") = _arg2;                      \
+       register long int __a2 asm ("$6") = _arg3;                      \
+       register long int __a3 asm ("$7") = _arg4;                      \
+       register long int __a4 asm ("$8") = _arg5;                      \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
        v0_init                                                         \
 #define internal_syscall6(v0_init, input, number, err,                 \
                          arg1, arg2, arg3, arg4, arg5, arg6)           \
 ({                                                                     \
-       long _sys_result;                                               \
+       long int _sys_result;                                           \
                                                                        \
        {                                                               \
-       register long __s0 asm ("$16") __attribute__ ((unused))         \
+       long int _arg1 = (long int) (arg1);                             \
+       long int _arg2 = (long int) (arg2);                             \
+       long int _arg3 = (long int) (arg3);                             \
+       long int _arg4 = (long int) (arg4);                             \
+       long int _arg5 = (long int) (arg5);                             \
+       long int _arg6 = (long int) (arg6);                             \
+       register long int __s0 asm ("$16") __attribute__ ((unused))     \
          = (number);                                                   \
-       register long __v0 asm ("$2");                                  \
-       register long __a0 asm ("$4") = (long) (arg1);                  \
-       register long __a1 asm ("$5") = (long) (arg2);                  \
-       register long __a2 asm ("$6") = (long) (arg3);                  \
-       register long __a3 asm ("$7") = (long) (arg4);                  \
-       register long __a4 asm ("$8") = (long) (arg5);                  \
-       register long __a5 asm ("$9") = (long) (arg6);                  \
+       register long int __v0 asm ("$2");                              \
+       register long int __a0 asm ("$4") = _arg1;                      \
+       register long int __a1 asm ("$5") = _arg2;                      \
+       register long int __a2 asm ("$6") = _arg3;                      \
+       register long int __a3 asm ("$7") = _arg4;                      \
+       register long int __a4 asm ("$8") = _arg5;                      \
+       register long int __a5 asm ("$9") = _arg6;                      \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
        v0_init                                                         \
 #define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...)              \
   ({                                                                   \
     long _ret = funcptr (args);                                                \
-    err = ((unsigned long) (_ret) >= (unsigned long) -4095L);          \
+    err = ((unsigned long) (_ret) >= (unsigned long int) -4095L);      \
     if (err)                                                           \
       _ret = -_ret;                                                    \
     _ret;                                                              \
index 50a6e6dbe9ef557d46fdb87a5ccb7ab64b8fdc2b..251d5909967311f2c9c70cda6ee9e72428c0ca71 100644 (file)
@@ -20,7 +20,7 @@
 #include <sys/asm.h>
 
 /* Usage:
-   long syscall (syscall_number, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+   long int syscall (syscall_number, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
 
    We need to do some arg shifting, syscall_number will be in v0.  */
 
index 16cc31cba5b4d046df94aa8fb331d1ebbade0f87..bf7d80125af954bc8f824b2b217f935faab0f636 100644 (file)
@@ -43,6 +43,9 @@ __typeof (openat64) __openat64_nocancel;
 /* Non cancellable read syscall.  */
 __typeof (__read) __read_nocancel;
 
+/* Non cancellable pread syscall (LFS version).  */
+__typeof (__pread64) __pread64_nocancel;
+
 /* Uncancelable write.  */
 __typeof (__write) __write_nocancel;
 
@@ -84,6 +87,7 @@ hidden_proto (__open64_nocancel)
 hidden_proto (__openat_nocancel)
 hidden_proto (__openat64_nocancel)
 hidden_proto (__read_nocancel)
+hidden_proto (__pread64_nocancel)
 hidden_proto (__write_nocancel)
 hidden_proto (__close_nocancel)
 hidden_proto (__waitpid_nocancel)
diff --git a/sysdeps/unix/sysv/linux/pread64_nocancel.c b/sysdeps/unix/sysv/linux/pread64_nocancel.c
new file mode 100644 (file)
index 0000000..dab6126
--- /dev/null
@@ -0,0 +1,32 @@
+/* Linux pread64() syscall implementation -- non-cancellable.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <unistd.h>
+#include <sysdep-cancel.h>
+#include <not-cancel.h>
+
+#ifndef __NR_pread64
+# define __NR_pread64 __NR_pread
+#endif
+
+ssize_t
+__pread64_nocancel (int fd, void *buf, size_t count, off64_t offset)
+{
+  return INLINE_SYSCALL_CALL (pread64, fd, buf, count, SYSCALL_LL64_PRW (offset));
+}
+hidden_def (__pread64_nocancel)
index 5470ea3d2a6882ad34e5fc924517fd6fc98add2b..6fc63852cfc3f1b3329823dbe0c68b6936151b8e 100644 (file)
 # define internal_syscall1(number, err, arg0)                          \
 ({                                                                     \
        long int _sys_result;                                           \
+       long int _arg0 = (long int) (arg0);                             \
                                                                        \
        {                                                               \
        register long int __a7 asm ("a7") = number;                     \
-       register long int __a0 asm ("a0") = (long int) (arg0);          \
+       register long int __a0 asm ("a0") = _arg0;                      \
        __asm__ volatile (                                              \
        "scall\n\t"                                                     \
        : "+r" (__a0)                                                   \
 # define internal_syscall2(number, err, arg0, arg1)                    \
 ({                                                                     \
        long int _sys_result;                                           \
+       long int _arg0 = (long int) (arg0);                             \
+       long int _arg1 = (long int) (arg1);                             \
                                                                        \
        {                                                               \
        register long int __a7 asm ("a7") = number;                     \
-       register long int __a0 asm ("a0") = (long int) (arg0);          \
-       register long int __a1 asm ("a1") = (long int) (arg1);          \
+       register long int __a0 asm ("a0") = _arg0;                      \
+       register long int __a1 asm ("a1") = _arg1;                      \
        __asm__ volatile (                                              \
        "scall\n\t"                                                     \
        : "+r" (__a0)                                                   \
 # define internal_syscall3(number, err, arg0, arg1, arg2)                      \
 ({                                                                     \
        long int _sys_result;                                           \
+       long int _arg0 = (long int) (arg0);                             \
+       long int _arg1 = (long int) (arg1);                             \
+       long int _arg2 = (long int) (arg2);                             \
                                                                        \
        {                                                               \
        register long int __a7 asm ("a7") = number;                     \
-       register long int __a0 asm ("a0") = (long int) (arg0);          \
-       register long int __a1 asm ("a1") = (long int) (arg1);          \
-       register long int __a2 asm ("a2") = (long int) (arg2);          \
+       register long int __a0 asm ("a0") = _arg0;                      \
+       register long int __a1 asm ("a1") = _arg1;                      \
+       register long int __a2 asm ("a2") = _arg2;                      \
        __asm__ volatile (                                              \
        "scall\n\t"                                                     \
        : "+r" (__a0)                                                   \
 # define internal_syscall4(number, err, arg0, arg1, arg2, arg3)          \
 ({                                                                     \
        long int _sys_result;                                           \
+       long int _arg0 = (long int) (arg0);                             \
+       long int _arg1 = (long int) (arg1);                             \
+       long int _arg2 = (long int) (arg2);                             \
+       long int _arg3 = (long int) (arg3);                             \
                                                                        \
        {                                                               \
        register long int __a7 asm ("a7") = number;                     \
-       register long int __a0 asm ("a0") = (long int) (arg0);          \
-       register long int __a1 asm ("a1") = (long int) (arg1);          \
-       register long int __a2 asm ("a2") = (long int) (arg2);          \
-       register long int __a3 asm ("a3") = (long int) (arg3);          \
+       register long int __a0 asm ("a0") = _arg0;                      \
+       register long int __a1 asm ("a1") = _arg1;                      \
+       register long int __a2 asm ("a2") = _arg2;                      \
+       register long int __a3 asm ("a3") = _arg3;                      \
        __asm__ volatile (                                              \
        "scall\n\t"                                                     \
        : "+r" (__a0)                                                   \
 # define internal_syscall5(number, err, arg0, arg1, arg2, arg3, arg4)   \
 ({                                                                     \
        long int _sys_result;                                           \
+       long int _arg0 = (long int) (arg0);                             \
+       long int _arg1 = (long int) (arg1);                             \
+       long int _arg2 = (long int) (arg2);                             \
+       long int _arg3 = (long int) (arg3);                             \
+       long int _arg4 = (long int) (arg4);                             \
                                                                        \
        {                                                               \
        register long int __a7 asm ("a7") = number;                     \
-       register long int __a0 asm ("a0") = (long int) (arg0);          \
-       register long int __a1 asm ("a1") = (long int) (arg1);          \
-       register long int __a2 asm ("a2") = (long int) (arg2);          \
-       register long int __a3 asm ("a3") = (long int) (arg3);          \
-       register long int __a4 asm ("a4") = (long int) (arg4);          \
+       register long int __a0 asm ("a0") = _arg0;                      \
+       register long int __a1 asm ("a1") = _arg1;                      \
+       register long int __a2 asm ("a2") = _arg2;                      \
+       register long int __a3 asm ("a3") = _arg3;                      \
+       register long int __a4 asm ("a4") = _arg4;                      \
        __asm__ volatile (                                              \
        "scall\n\t"                                                     \
        : "+r" (__a0)                                                   \
 # define internal_syscall6(number, err, arg0, arg1, arg2, arg3, arg4, arg5) \
 ({                                                                     \
        long int _sys_result;                                           \
+       long int _arg0 = (long int) (arg0);                             \
+       long int _arg1 = (long int) (arg1);                             \
+       long int _arg2 = (long int) (arg2);                             \
+       long int _arg3 = (long int) (arg3);                             \
+       long int _arg4 = (long int) (arg4);                             \
+       long int _arg5 = (long int) (arg5);                             \
                                                                        \
        {                                                               \
        register long int __a7 asm ("a7") = number;                     \
-       register long int __a0 asm ("a0") = (long int) (arg0);          \
-       register long int __a1 asm ("a1") = (long int) (arg1);          \
-       register long int __a2 asm ("a2") = (long int) (arg2);          \
-       register long int __a3 asm ("a3") = (long int) (arg3);          \
-       register long int __a4 asm ("a4") = (long int) (arg4);          \
-       register long int __a5 asm ("a5") = (long int) (arg5);          \
+       register long int __a0 asm ("a0") = _arg0;                      \
+       register long int __a1 asm ("a1") = _arg1;                      \
+       register long int __a2 asm ("a2") = _arg2;                      \
+       register long int __a3 asm ("a3") = _arg3;                      \
+       register long int __a4 asm ("a4") = _arg4;                      \
+       register long int __a5 asm ("a5") = _arg5;                      \
        __asm__ volatile (                                              \
        "scall\n\t"                                                     \
        : "+r" (__a0)                                                   \
 # define internal_syscall7(number, err, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
 ({                                                                     \
        long int _sys_result;                                           \
+       long int _arg0 = (long int) (arg0);                             \
+       long int _arg1 = (long int) (arg1);                             \
+       long int _arg2 = (long int) (arg2);                             \
+       long int _arg3 = (long int) (arg3);                             \
+       long int _arg4 = (long int) (arg4);                             \
+       long int _arg5 = (long int) (arg5);                             \
+       long int _arg6 = (long int) (arg6);                             \
                                                                        \
        {                                                               \
        register long int __a7 asm ("a7") = number;                     \
-       register long int __a0 asm ("a0") = (long int) (arg0);          \
-       register long int __a1 asm ("a1") = (long int) (arg1);          \
-       register long int __a2 asm ("a2") = (long int) (arg2);          \
-       register long int __a3 asm ("a3") = (long int) (arg3);          \
-       register long int __a4 asm ("a4") = (long int) (arg4);          \
-       register long int __a5 asm ("a5") = (long int) (arg5);          \
-       register long int __a6 asm ("a6") = (long int) (arg6);          \
+       register long int __a0 asm ("a0") = _arg0;                      \
+       register long int __a1 asm ("a1") = _arg1;                      \
+       register long int __a2 asm ("a2") = _arg2;                      \
+       register long int __a3 asm ("a3") = _arg3;                      \
+       register long int __a4 asm ("a4") = _arg4;                      \
+       register long int __a5 asm ("a5") = _arg5;                      \
+       register long int __a6 asm ("a6") = _arg6;                      \
        __asm__ volatile (                                              \
        "scall\n\t"                                                     \
        : "+r" (__a0)                                                   \
index 67373f181b235c8717754fb0ce89b115c3bee9e6..dc173d6b47e91dc0f50933e1d2c9313d85abe083 100644 (file)
 #include <sys/asm.h>
 #include <sysdep.h>
 #define __ASSEMBLY__
-#include <linux/sched.h>
 #include <asm/signal.h>
 
+#define CLONE_VM      0x00000100 /* Set if VM shared between processes.  */
+#define CLONE_VFORK   0x00004000 /* Set if the parent wants the child to
+                                   wake it up on mm_release.  */
+
        .text
 LEAF (__libc_vfork)
 
index 862115c6f88870a2698b3e3d717194afe3010525..0569c3b784b8de6be04e668c7e01e0e522d408cc 100644 (file)
@@ -61,7 +61,8 @@ struct utmp
   pid_t ut_pid;                        /* Process ID of login process.  */
   char ut_line[UT_LINESIZE]
      __attribute_nonstring__;  /* Devicename.  */
-  char ut_id[4];               /* Inittab ID.  */
+  char ut_id[4]
+    __attribute_nonstring__;   /* Inittab ID.  */
   char ut_user[UT_NAMESIZE]
      __attribute_nonstring__;  /* Username.  */
   char ut_host[UT_HOSTSIZE]
index ea3e860a2d28aad0da099b73cd1e2470523e0556..737d9dca054aa832c76968e4bb2dc651111c2b57 100644 (file)
@@ -56,10 +56,14 @@ struct utmpx
 {
   short int ut_type;           /* Type of login.  */
   __pid_t ut_pid;              /* Process ID of login process.  */
-  char ut_line[__UT_LINESIZE]; /* Devicename.  */
-  char ut_id[4];               /* Inittab ID. */
-  char ut_user[__UT_NAMESIZE]; /* Username.  */
-  char ut_host[__UT_HOSTSIZE]; /* Hostname for remote login.  */
+  char ut_line[__UT_LINESIZE]
+    __attribute_nonstring__;   /* Devicename.  */
+  char ut_id[4]
+    __attribute_nonstring__;   /* Inittab ID.  */
+  char ut_user[__UT_NAMESIZE]
+    __attribute_nonstring__;   /* Username.  */
+  char ut_host[__UT_HOSTSIZE]
+    __attribute_nonstring__;   /* Hostname for remote login.  */
   struct __exit_status ut_exit;        /* Exit status of a process marked
                                   as DEAD_PROCESS.  */
 
index fb3ee5b8a1e0d90a2b082dfbd3727e13c3249c74..7b91ff182487472451251835120b8ef87cba4b84 100644 (file)
@@ -15,8 +15,12 @@ ifeq ($(subdir),sysvipc)
 sysdep_routines += getshmlba
 endif
 
+ifeq ($(subdir),signal)
+sysdep_routines += sigreturn_stub
+endif
+
 ifeq ($(subdir),nptl)
 # pull in __syscall_error routine
-libpthread-routines += sysdep
-libpthread-shared-only-routines += sysdep
+libpthread-routines += sysdep sigreturn_stub
+libpthread-shared-only-routines += sysdep sigreturn_stub
 endif
index de7ef6f151c2206a2bf5a4b9f209df36366e92a4..f36e924af40197cc101a3277a46d741a3963314a 100644 (file)
@@ -24,8 +24,8 @@
 #include <kernel_sigaction.h>
 #include <sysdep.h>
 
-static void __rt_sigreturn_stub (void);
-static void __sigreturn_stub (void);
+void __rt_sigreturn_stub (void);
+void __sigreturn_stub (void);
 
 #define STUB(act, sigsetsize) \
   (act) ? ((unsigned long)((act->sa_flags & SA_SIGINFO)        \
@@ -35,25 +35,3 @@ static void __sigreturn_stub (void);
   (sigsetsize)
 
 #include <sysdeps/unix/sysv/linux/sigaction.c>
-
-static
-inhibit_stack_protector
-void
-__rt_sigreturn_stub (void)
-{
-  __asm__ ("mov %0, %%g1\n\t"
-          "ta  0x10\n\t"
-          : /* no outputs */
-          : "i" (__NR_rt_sigreturn));
-}
-
-static
-inhibit_stack_protector
-void
-__sigreturn_stub (void)
-{
-  __asm__ ("mov %0, %%g1\n\t"
-          "ta  0x10\n\t"
-          : /* no outputs */
-          : "i" (__NR_sigreturn));
-}
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S b/sysdeps/unix/sysv/linux/sparc/sparc32/sigreturn_stub.S
new file mode 100644 (file)
index 0000000..727cc94
--- /dev/null
@@ -0,0 +1,34 @@
+/* Sigreturn stub function used on sa_restore field.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* These functions must not change the register window or the stack
+   pointer [1].
+
+   [1] https://lkml.org/lkml/2016/5/27/465  */
+
+ENTRY (__rt_sigreturn_stub)
+       mov     __NR_rt_sigreturn, %g1
+       ta      0x10
+END (__rt_sigreturn_stub)
+
+ENTRY (__sigreturn_stub)
+       mov     __NR_sigreturn, %g1
+       ta      0x10
+END (__sigreturn_stub)
index 3b8be43c07fc7a283d5cbfb80c54abb538dbe547..4772ec2553cc90811492355feae69cd189f66778 100644 (file)
 #include <syscall.h>
 #include <sysdep.h>
 
-static void __rt_sigreturn_stub (void);
+/* Defined on sigreturn_stub.S.  */
+void __rt_sigreturn_stub (void);
 
 #define STUB(act, sigsetsize) \
   (((unsigned long) &__rt_sigreturn_stub) - 8),        \
   (sigsetsize)
 
 #include <sysdeps/unix/sysv/linux/sigaction.c>
-
-static
-inhibit_stack_protector
-void
-__rt_sigreturn_stub (void)
-{
-  __asm__ ("mov %0, %%g1\n\t"
-          "ta  0x6d\n\t"
-          : /* no outputs */
-          : "i" (__NR_rt_sigreturn));
-}
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sigreturn_stub.S b/sysdeps/unix/sysv/linux/sparc/sparc64/sigreturn_stub.S
new file mode 100644 (file)
index 0000000..add4766
--- /dev/null
@@ -0,0 +1,29 @@
+/* Sigreturn stub function used on sa_restore field.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+/* This function must not change the register window or the stack
+   pointer [1].
+
+   [1] https://lkml.org/lkml/2016/5/27/465  */
+
+ENTRY (__rt_sigreturn_stub)
+       mov     __NR_rt_sigreturn, %g1
+       ta      0x6d
+END (__rt_sigreturn_stub)
index cb979d44bd31225558322c37f278f00baa32264e..aaa9eadc0a4076fa08d499279dcfd394b2db0174 100644 (file)
@@ -160,8 +160,9 @@ do_test (void)
   fails |= test_wrp (EINVAL, poll, &pollfd, -1, 0);
   /* quotactl returns ENOSYS for kernels not configured with
      CONFIG_QUOTA, and may return EPERM if called within certain types
-     of containers.  */
-  fails |= test_wrp2 (LIST (ENODEV, ENOSYS, EPERM),
+     of containers.  Linux 5.4 added additional argument validation
+     and can return EINVAL.  */
+  fails |= test_wrp2 (LIST (ENODEV, ENOSYS, EPERM, EINVAL),
                      quotactl, Q_GETINFO, NULL, -1, (caddr_t) &dqblk);
   fails |= test_wrp (EINVAL, sched_getparam, -1, &sch_param);
   fails |= test_wrp (EINVAL, sched_getscheduler, -1);
index 975cbe2950e2a9524ddf2e3ac17d9cc7317954c9..df2cdfdb6b3260554c58990daf200b244dce3103 100644 (file)
@@ -31,7 +31,8 @@
    environment variable, LD_PREFER_MAP_32BIT_EXEC.  */
 #define EXTRA_LD_ENVVARS \
   case 21:                                                               \
-    if (memcmp (envline, "PREFER_MAP_32BIT_EXEC", 21) == 0)              \
+    if (!__libc_enable_secure                                            \
+       && memcmp (envline, "PREFER_MAP_32BIT_EXEC", 21) == 0)            \
       GLRO(dl_x86_cpu_features).feature[index_arch_Prefer_MAP_32BIT_EXEC] \
        |= bit_arch_Prefer_MAP_32BIT_EXEC;                                \
     break;
index a428f5524573260161f7791855c73da4badccdda..63b8d735ea99980dde455426b9672e85cfb05cfd 100644 (file)
@@ -57,6 +57,8 @@ include ../gen-locales.mk
 
 $(objpfx)tst-ftime_l.out: $(gen-locales)
 $(objpfx)tst-strptime.out: $(gen-locales)
+$(objpfx)tst-strftime2.out: $(gen-locales)
+$(objpfx)tst-strftime3.out: $(gen-locales)
 endif
 
 tz-cflags = -DTZDIR='"$(zonedir)"' \