git-updates
authorGNU Libc Maintainers <debian-glibc@lists.debian.org>
Tue, 4 Aug 2020 15:02:38 +0000 (16:02 +0100)
committerAurelien Jarno <aurel32@debian.org>
Tue, 4 Aug 2020 15:02:38 +0000 (16:02 +0100)
GIT update of https://sourceware.org/git/glibc.git/release/2.31/master from glibc-2.31

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

Gbp-Pq: Name git-updates.diff

96 files changed:
NEWS
configure
configure.ac
debug/backtrace.c
iconv/Makefile
iconv/Versions
iconv/gconv_charset.c [new file with mode: 0644]
iconv/gconv_charset.h
iconv/gconv_int.h
iconv/gconv_open.c
iconv/iconv_open.c
iconv/iconv_prog.c
iconv/tst-iconv-opt.c [new file with mode: 0644]
iconv/tst-iconv_prog.sh [new file with mode: 0644]
include/sys/prctl.h
intl/dcigettext.c
localedata/locales/oc_FR
malloc/tst-mallocfork2.c
math/Makefile
misc/Makefile
misc/tst-syscalls.c [new file with mode: 0644]
nptl/Makefile
nptl/descr.h
nptl/tst-setgroups.c [new file with mode: 0644]
nscd/selinux.c
nss/makedb.c
nss/nss_compat/compat-grp.c
nss/nss_compat/compat-initgroups.c
nss/nss_compat/compat-pwd.c
nss/nss_compat/compat-spwd.c
posix/glob.c
stdlib/Makefile
stdlib/tst-system.c
support/shell-container.c
sysdeps/aarch64/strcpy.S
sysdeps/aarch64/strnlen.S
sysdeps/arm/armv7/multiarch/memcpy_impl.S
sysdeps/arm/be/nofpu/Implies [new file with mode: 0644]
sysdeps/arm/le/nofpu/Implies [new file with mode: 0644]
sysdeps/arm/memcpy.S
sysdeps/arm/memmove.S
sysdeps/generic/unwind-arch.h [new file with mode: 0644]
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/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/sysdep.h
sysdeps/unix/make-syscalls.sh
sysdeps/unix/syscall-template.S
sysdeps/unix/syscalls.list
sysdeps/unix/sysv/linux/Makefile
sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
sysdeps/unix/sysv/linux/aarch64/localplt.data
sysdeps/unix/sysv/linux/hppa/atomic-machine.h
sysdeps/unix/sysv/linux/microblaze/sysdep.h
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/mips/sysdep.h
sysdeps/unix/sysv/linux/mips/unwind-arch.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/msgctl.c
sysdeps/unix/sysv/linux/nios2/kernel-features.h [deleted file]
sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
sysdeps/unix/sysv/linux/prctl.c [new file with mode: 0644]
sysdeps/unix/sysv/linux/process_vm_readv.c [new file with mode: 0644]
sysdeps/unix/sysv/linux/process_vm_writev.c [new file with mode: 0644]
sysdeps/unix/sysv/linux/riscv/sysdep.h
sysdeps/unix/sysv/linux/semctl.c
sysdeps/unix/sysv/linux/shmctl.c
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/syscall-names.list
sysdeps/unix/sysv/linux/syscalls.list
sysdeps/unix/sysv/linux/x86_64/sysdep.h
sysdeps/unix/sysv/linux/x86_64/x32/sysdep.h
sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S
sysdeps/x86_64/multiarch/strcmp-avx2.S

diff --git a/NEWS b/NEWS
index 292fbc595a62f2d9e06777abd453894599118b27..d3ffb822942fa6c9f35301bbfab70a4670d6f9ee 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,52 @@ 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.31.1
+
+The following bugs are resolved with this release:
+  [19519] iconv(1) with -c option hangs on illegal multi-byte sequences
+    (CVE-2016-10228)
+  [20543] Please move from .gnu.linkonce to comdat
+  [23296] Data race in setting function descriptor during lazy binding
+  [25487] sinl() stack corruption from crafted input (CVE-2020-10029)
+  [25523] MIPS/Linux inline syscall template is miscompiled
+  [25623] test-sysvmsg, test-sysvsem, test-sysvshm fail with 2.31 on 32 bit and
+    old kernel
+  [25635] arm: Wrong sysdep order selection for soft-fp
+  [25639] localedata: Some names of days and months wrongly spelt in
+    Occitan
+  [25715] system() returns wrong errors when posix_spawn fails
+  [25810] x32: Incorrect syscall entries with pointer, off_t and size_t
+  [25896] Incorrect prctl
+  [25902] Bad LOADARGS_N
+  [25933] Off by one error in __strncmp_avx2
+  [25966] Incorrect access of __x86_shared_non_temporal_threshold for x32
+  [25976] nss_compat: internal_end*ent may clobber errno, hiding ERANGE
+  [26248] Incorrect argument types for INLINE_SETXID_SYSCALL
+  [26332] Incorrect cache line size load causes memory corruption in memset
+
+Security related changes:
+
+  CVE-2016-10228: An infinite loop has been fixed in the iconv program when
+  invoked with the -c option and when processing invalid multi-byte input
+  sequences.  Reported by Jan Engelhardt.
+
+  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.
+
+  CVE-2020-6096: A signed comparison vulnerability in the ARMv7 memcpy and
+  memmove functions has been fixed.  Discovered by Jason Royes and Samual
+  Dytrych of the Cisco Security Assessment and Penetration Team (See
+  TALOS-2020-1019).
+
 \f
 Version 2.31
 
index b959d2d9885e53e6adcd7037f8382720555abd40..3b98ec312fc9c8cc605453654a6ca72106ca0185 100755 (executable)
--- a/configure
+++ b/configure
@@ -4035,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 49b900c1ed68fa4dd1dadca809ceb6e8b237a89c..e20034f301fd7d04ab1c4499bfc1eacdb316570c 100644 (file)
@@ -649,7 +649,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 cc4b9a5c904158e28b1b24400a6b5826f768dd8d..69cf4c23c85a969fea90d2658fbc72dc15951c70 100644 (file)
@@ -23,6 +23,7 @@
 #include <gnu/lib-names.h>
 #include <stdlib.h>
 #include <unwind.h>
+#include <unwind-arch.h>
 
 struct trace_arg
 {
@@ -78,6 +79,10 @@ backtrace_helper (struct _Unwind_Context *ctx, void *a)
   if (arg->cnt != -1)
     {
       arg->array[arg->cnt] = (void *) unwind_getip (ctx);
+      if (arg->cnt > 0)
+       arg->array[arg->cnt]
+         = unwind_arch_adjustment (arg->array[arg->cnt - 1],
+                                   arg->array[arg->cnt]);
 
       /* Check whether we make any progress.  */
       _Unwind_Word cfa = unwind_getcfa (ctx);
index b8fe8c47df37d6dc24c08ed5b9d1638cbbc67a04..30bf996d3a7266ae79b1d0f4b6a324506517a6c3 100644 (file)
@@ -26,7 +26,7 @@ headers               = iconv.h gconv.h
 routines       = iconv_open iconv iconv_close \
                  gconv_open gconv gconv_close gconv_db gconv_conf \
                  gconv_builtin gconv_simple gconv_trans gconv_cache
-routines       += gconv_dl
+routines       += gconv_dl gconv_charset
 
 vpath %.c ../locale/programs ../intl
 
@@ -44,7 +44,7 @@ CFLAGS-linereader.c += -DNO_TRANSLITERATION
 CFLAGS-simple-hash.c += -I../locale
 
 tests  = tst-iconv1 tst-iconv2 tst-iconv3 tst-iconv4 tst-iconv5 tst-iconv6 \
-         tst-iconv7 tst-iconv-mt
+         tst-iconv7 tst-iconv-mt tst-iconv-opt
 
 others         = iconv_prog iconvconfig
 install-others-programs        = $(inst_bindir)/iconv
@@ -61,6 +61,7 @@ include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left))
 
 ifeq ($(run-built-tests),yes)
 xtests-special += $(objpfx)test-iconvconfig.out
+tests-special += $(objpfx)tst-iconv_prog.out
 endif
 
 # Make a copy of the file because gconv module names are constructed
@@ -81,6 +82,13 @@ endif
 
 include ../Rules
 
+ifeq ($(run-built-tests),yes)
+LOCALES := en_US.UTF-8
+include ../gen-locales.mk
+
+$(objpfx)tst-iconv-opt.out: $(gen-locales)
+endif
+
 $(inst_bindir)/iconv: $(objpfx)iconv_prog $(+force)
        $(do-install-program)
 
@@ -95,3 +103,8 @@ $(objpfx)test-iconvconfig.out: /dev/null $(objpfx)iconvconfig
         cmp $$tmp $(inst_gconvdir)/gconv-modules.cache; \
         rm -f $$tmp) > $@; \
        $(evaluate-test)
+
+$(objpfx)tst-iconv_prog.out: tst-iconv_prog.sh $(objpfx)iconv_prog
+       $(BASH) $< $(common-objdir) '$(test-wrapper-env)' \
+                '$(run-program-env)' > $@; \
+       $(evaluate-test)
index 60ab10a2775885157b8e9ae6f0871c514fc3cb86..8a5f4cf780b18925902b0cfa98630e393b8fa439 100644 (file)
@@ -6,6 +6,7 @@ libc {
   GLIBC_PRIVATE {
     # functions shared with iconv program
     __gconv_get_alias_db; __gconv_get_cache; __gconv_get_modules_db;
+    __gconv_open; __gconv_create_spec;
 
     # function used by the gconv modules
     __gconv_transliterate;
diff --git a/iconv/gconv_charset.c b/iconv/gconv_charset.c
new file mode 100644 (file)
index 0000000..6ccd077
--- /dev/null
@@ -0,0 +1,218 @@
+/* Charset name normalization.
+   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
+   <http://www.gnu.org/licenses/>.  */
+
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <locale.h>
+#include <stdbool.h>
+#include <string.h>
+#include <sys/stat.h>
+#include "gconv_int.h"
+#include "gconv_charset.h"
+
+
+/* This function returns a pointer to the last suffix in a conversion code
+   string.  Valid suffixes matched by this function are of the form: '/' or ','
+   followed by arbitrary text that doesn't contain '/' or ','.  It does not
+   edit the string in any way.  The caller is expected to parse the suffix and
+   remove it (by e.g. truncating the string) before the next call.  */
+static char *
+find_suffix (char *s)
+{
+  /* The conversion code is in the form of a triplet, separated by '/' chars.
+     The third component of the triplet contains suffixes. If we don't have two
+     slashes, we don't have a suffix.  */
+
+  int slash_count = 0;
+  char *suffix_term = NULL;
+
+  for (int i = 0; s[i] != '\0'; i++)
+    switch (s[i])
+      {
+        case '/':
+          slash_count++;
+          /* Fallthrough */
+        case ',':
+          suffix_term = &s[i];
+      }
+
+  if (slash_count >= 2)
+    return suffix_term;
+
+  return NULL;
+}
+
+
+struct gconv_parsed_code
+{
+  char *code;
+  bool translit;
+  bool ignore;
+};
+
+
+/* This function parses an iconv_open encoding PC.CODE, strips any suffixes
+   (such as TRANSLIT or IGNORE) from it and sets corresponding flags in it.  */
+static void
+gconv_parse_code (struct gconv_parsed_code *pc)
+{
+  pc->translit = false;
+  pc->ignore = false;
+
+  while (1)
+    {
+      /* First drop any trailing whitespaces and separators.  */
+      size_t len = strlen (pc->code);
+      while ((len > 0)
+             && (isspace (pc->code[len - 1])
+                 || pc->code[len - 1] == ','
+                 || pc->code[len - 1] == '/'))
+        len--;
+
+      pc->code[len] = '\0';
+
+      if (len == 0)
+        return;
+
+      char * suffix = find_suffix (pc->code);
+      if (suffix == NULL)
+        {
+          /* At this point, we have processed and removed all suffixes from the
+             code and what remains of the code is suffix free.  */
+          return;
+        }
+      else
+        {
+          /* A suffix is processed from the end of the code array going
+             backwards, one suffix at a time.  The suffix is an index into the
+             code character array and points to: one past the end of the code
+             and any unprocessed suffixes, and to the beginning of the suffix
+             currently being processed during this iteration.  We must process
+             this suffix and then drop it from the code by terminating the
+             preceding text with NULL.
+
+             We want to allow and recognize suffixes such as:
+
+             "/TRANSLIT"         i.e. single suffix
+             "//TRANSLIT"        i.e. single suffix and multiple separators
+             "//TRANSLIT/IGNORE" i.e. suffixes separated by "/"
+             "/TRANSLIT//IGNORE" i.e. suffixes separated by "//"
+             "//IGNORE,TRANSLIT" i.e. suffixes separated by ","
+             "//IGNORE,"         i.e. trailing ","
+             "//TRANSLIT/"       i.e. trailing "/"
+             "//TRANSLIT//"      i.e. trailing "//"
+             "/"                 i.e. empty suffix.
+
+             Unknown suffixes are silently discarded and ignored.  */
+
+          if ((__strcasecmp_l (suffix,
+                               GCONV_TRIPLE_SEPARATOR
+                               GCONV_TRANSLIT_SUFFIX,
+                               _nl_C_locobj_ptr) == 0)
+              || (__strcasecmp_l (suffix,
+                                  GCONV_SUFFIX_SEPARATOR
+                                  GCONV_TRANSLIT_SUFFIX,
+                                  _nl_C_locobj_ptr) == 0))
+            pc->translit = true;
+
+          if ((__strcasecmp_l (suffix,
+                               GCONV_TRIPLE_SEPARATOR
+                               GCONV_IGNORE_ERRORS_SUFFIX,
+                               _nl_C_locobj_ptr) == 0)
+              || (__strcasecmp_l (suffix,
+                                  GCONV_SUFFIX_SEPARATOR
+                                  GCONV_IGNORE_ERRORS_SUFFIX,
+                                  _nl_C_locobj_ptr) == 0))
+            pc->ignore = true;
+
+          /* We just processed this suffix.  We can now drop it from the
+             code string by truncating it at the suffix's position.  */
+          suffix[0] = '\0';
+        }
+    }
+}
+
+
+/* This function accepts the charset names of the source and destination of the
+   conversion and populates *conv_spec with an equivalent conversion
+   specification that may later be used by __gconv_open.  The charset names
+   might contain options in the form of suffixes that alter the conversion,
+   e.g. "ISO-10646/UTF-8/TRANSLIT".  It processes the charset names, ignoring
+   and truncating any suffix options in fromcode, and processing and truncating
+   any suffix options in tocode.  Supported suffix options ("TRANSLIT" or
+   "IGNORE") when found in tocode lead to the corresponding flag in *conv_spec
+   to be set to true.  Unrecognized suffix options are silently discarded.  If
+   the function succeeds, it returns conv_spec back to the caller.  It returns
+   NULL upon failure.  conv_spec must be allocated and freed by the caller.  */
+struct gconv_spec *
+__gconv_create_spec (struct gconv_spec *conv_spec, const char *fromcode,
+                   const char *tocode)
+{
+  struct gconv_parsed_code pfc, ptc;
+  struct gconv_spec *ret = NULL;
+
+  pfc.code = __strdup (fromcode);
+  ptc.code = __strdup (tocode);
+
+  if ((pfc.code == NULL)
+      || (ptc.code == NULL))
+    goto out;
+
+  gconv_parse_code (&pfc);
+  gconv_parse_code (&ptc);
+
+  /* We ignore suffixes in the fromcode because that is how the current
+     implementation has always handled them.  Only suffixes in the tocode are
+     processed and handled.  The reality is that invalid input in the input
+     character set should only be ignored if the fromcode specifies IGNORE.
+     The current implementation ignores invalid intput in the input character
+     set if the tocode contains IGNORE.  We preserve this behavior for
+     backwards compatibility.  In the future we may split the handling of
+     IGNORE to allow a finer grained specification of ignorning invalid input
+     and/or ignoring invalid output.  */
+  conv_spec->translit = ptc.translit;
+  conv_spec->ignore = ptc.ignore;
+
+  /* 3 extra bytes because 1 extra for '\0', and 2 extra so strip might
+     be able to add one or two trailing '/' characters if necessary.  */
+  conv_spec->fromcode = malloc (strlen (fromcode) + 3);
+  if (conv_spec->fromcode == NULL)
+    goto out;
+
+  conv_spec->tocode = malloc (strlen (tocode) + 3);
+  if (conv_spec->tocode == NULL)
+    {
+      free (conv_spec->fromcode);
+      conv_spec->fromcode = NULL;
+      goto out;
+    }
+
+  /* Strip unrecognized characters and ensure that the code has two '/'
+     characters as per conversion code triplet specification.  */
+  strip (conv_spec->fromcode, pfc.code);
+  strip (conv_spec->tocode, ptc.code);
+  ret = conv_spec;
+
+out:
+  free (pfc.code);
+  free (ptc.code);
+
+  return ret;
+}
+libc_hidden_def (__gconv_create_spec)
index 348acc089b76f9b7504ea701ecce5131f26dd14b..b39b09aea1d2906d8b68c73f0bc02f5fd3e8d088 100644 (file)
 
 #include <ctype.h>
 #include <locale.h>
+#include <stdbool.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include "gconv_int.h"
 
 
-static void
+/* An iconv encoding is in the form of a triplet, with parts separated by
+   a '/' character.  The first part is the standard name, the second part is
+   the character set, and the third part is the error handler.  If the first
+   part is sufficient to identify both the standard and the character set
+   then the second part can be empty e.g. UTF-8//.  If the first part is not
+   sufficient to identify both the standard and the character set then the
+   second part is required e.g. ISO-10646/UTF8/.  If neither the first or
+   second parts are provided e.g. //, then the current locale is used.
+   The actual values used in the first and second parts are not entirely
+   relevant to the implementation.  The values themselves are used in a hash
+   table to lookup modules and so the naming convention of the first two parts
+   is somewhat arbitrary and only helps locate the entries in the cache.
+   The third part is the error handler and is comprised of a ',' or '/'
+   separated list of suffixes.  Currently, we support "TRANSLIT" for
+   transliteration and "IGNORE" for ignoring conversion errors due to
+   unrecognized input characters.  */
+#define GCONV_TRIPLE_SEPARATOR "/"
+#define GCONV_SUFFIX_SEPARATOR ","
+#define GCONV_TRANSLIT_SUFFIX "TRANSLIT"
+#define GCONV_IGNORE_ERRORS_SUFFIX "IGNORE"
+
+
+/* This function accepts the charset names of the source and destination of the
+   conversion and populates *conv_spec with an equivalent conversion
+   specification that may later be used by __gconv_open.  The charset names
+   might contain options in the form of suffixes that alter the conversion,
+   e.g. "ISO-10646/UTF-8/TRANSLIT".  It processes the charset names, ignoring
+   and truncating any suffix options in fromcode, and processing and truncating
+   any suffix options in tocode.  Supported suffix options ("TRANSLIT" or
+   "IGNORE") when found in tocode lead to the corresponding flag in *conv_spec
+   to be set to true.  Unrecognized suffix options are silently discarded.  If
+   the function succeeds, it returns conv_spec back to the caller.  It returns
+   NULL upon failure.  */
+struct gconv_spec *
+__gconv_create_spec (struct gconv_spec *conv_spec, const char *fromcode,
+                     const char *tocode);
+libc_hidden_proto (__gconv_create_spec)
+
+
+/* This function frees all heap memory allocated by __gconv_create_spec.  */
+static void __attribute__ ((unused))
+gconv_destroy_spec (struct gconv_spec *conv_spec)
+{
+  free (conv_spec->fromcode);
+  free (conv_spec->tocode);
+  return;
+}
+
+
+/* This function copies in-order, characters from the source 's' that are
+   either alpha-numeric or one in one of these: "_-.,:/" - into the destination
+   'wp' while dropping all other characters.  In the process, it converts all
+   alphabetical characters to upper case.  It then appends up to two '/'
+   characters so that the total number of '/'es in the destination is 2.  */
+static inline void __attribute__ ((unused, always_inline))
 strip (char *wp, const char *s)
 {
   int slash_count = 0;
index fbaf12cee28ccfc35cd7d063d4791e6804dd4360..e86938dae7cf227daf23e4239a92ecf1651cb19d 100644 (file)
@@ -75,6 +75,15 @@ struct gconv_module
 };
 
 
+/* The specification of the conversion that needs to be performed.  */
+struct gconv_spec
+{
+  char *fromcode;
+  char *tocode;
+  bool translit;
+  bool ignore;
+};
+
 /* Flags for `gconv_open'.  */
 enum
 {
@@ -136,10 +145,12 @@ __libc_lock_define (extern, __gconv_lock attribute_hidden)
   })
 
 
-/* Return in *HANDLE decriptor for transformation from FROMSET to TOSET.  */
-extern int __gconv_open (const char *toset, const char *fromset,
-                        __gconv_t *handle, int flags)
-     attribute_hidden;
+/* Return in *HANDLE, a decriptor for the transformation.  The function expects
+   the specification of the transformation in the structure pointed to by
+   CONV_SPEC.  It only reads *CONV_SPEC and does not take ownership of it.  */
+extern int __gconv_open (struct gconv_spec *conv_spec,
+                         __gconv_t *handle, int flags);
+libc_hidden_proto (__gconv_open)
 
 /* Free resources associated with transformation descriptor CD.  */
 extern int __gconv_close (__gconv_t cd)
index b39626d252471be94a8a231c9bf2e52033ff998a..2878620957460d4634059e37225c72bebfdaa4d5 100644 (file)
@@ -31,7 +31,7 @@
 
 
 int
-__gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
+__gconv_open (struct gconv_spec *conv_spec, __gconv_t *handle,
              int flags)
 {
   struct __gconv_step *steps;
@@ -40,77 +40,38 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
   size_t cnt = 0;
   int res;
   int conv_flags = 0;
-  const char *errhand;
-  const char *ignore;
   bool translit = false;
+  char *tocode, *fromcode;
 
   /* Find out whether any error handling method is specified.  */
-  errhand = strchr (toset, '/');
-  if (errhand != NULL)
-    errhand = strchr (errhand + 1, '/');
-  if (__glibc_likely (errhand != NULL))
-    {
-      if (*++errhand == '\0')
-       errhand = NULL;
-      else
-       {
-         /* Make copy without the error handling description.  */
-         char *newtoset = (char *) alloca (errhand - toset + 1);
-         char *tok;
-         char *ptr = NULL /* Work around a bogus warning */;
-
-         newtoset[errhand - toset] = '\0';
-         toset = memcpy (newtoset, toset, errhand - toset);
+  translit = conv_spec->translit;
 
-         /* Find the appropriate transliteration handlers.  */
-         tok = strdupa (errhand);
+  if (conv_spec->ignore)
+    conv_flags |= __GCONV_IGNORE_ERRORS;
 
-         tok = __strtok_r (tok, ",", &ptr);
-         while (tok != NULL)
-           {
-             if (__strcasecmp_l (tok, "TRANSLIT", _nl_C_locobj_ptr) == 0)
-               translit = true;
-             else if (__strcasecmp_l (tok, "IGNORE", _nl_C_locobj_ptr) == 0)
-               /* Set the flag to ignore all errors.  */
-               conv_flags |= __GCONV_IGNORE_ERRORS;
-
-             tok = __strtok_r (NULL, ",", &ptr);
-           }
-       }
-    }
-
-  /* For the source character set we ignore the error handler specification.
-     XXX Is this really always the best?  */
-  ignore = strchr (fromset, '/');
-  if (ignore != NULL && (ignore = strchr (ignore + 1, '/')) != NULL
-      && *++ignore != '\0')
-    {
-      char *newfromset = (char *) alloca (ignore - fromset + 1);
-
-      newfromset[ignore - fromset] = '\0';
-      fromset = memcpy (newfromset, fromset, ignore - fromset);
-    }
+  tocode = conv_spec->tocode;
+  fromcode = conv_spec->fromcode;
 
   /* If the string is empty define this to mean the charset of the
      currently selected locale.  */
-  if (strcmp (toset, "//") == 0)
+  if (strcmp (tocode, "//") == 0)
     {
       const char *codeset = _NL_CURRENT (LC_CTYPE, CODESET);
       size_t len = strlen (codeset);
       char *dest;
-      toset = dest = (char *) alloca (len + 3);
+      tocode = dest = (char *) alloca (len + 3);
       memcpy (__mempcpy (dest, codeset, len), "//", 3);
     }
-  if (strcmp (fromset, "//") == 0)
+  if (strcmp (fromcode, "//") == 0)
     {
       const char *codeset = _NL_CURRENT (LC_CTYPE, CODESET);
       size_t len = strlen (codeset);
       char *dest;
-      fromset = dest = (char *) alloca (len + 3);
+      fromcode = dest = (char *) alloca (len + 3);
       memcpy (__mempcpy (dest, codeset, len), "//", 3);
     }
 
-  res = __gconv_find_transform (toset, fromset, &steps, &nsteps, flags);
+  res = __gconv_find_transform (tocode, fromcode, &steps, &nsteps, flags);
   if (res == __GCONV_OK)
     {
       /* Allocate room for handle.  */
@@ -209,3 +170,4 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
   *handle = result;
   return res;
 }
+libc_hidden_def (__gconv_open)
index 687067070a5e40cef44e2e5beb4ecb222251ebcc..dd54bc12e0e3990f0b76c95ecf97d4342eca971a 100644 (file)
 iconv_t
 iconv_open (const char *tocode, const char *fromcode)
 {
-  /* Normalize the name.  We remove all characters beside alpha-numeric,
-     '_', '-', '/', '.', and ':'.  */
-  size_t tocode_len = strlen (tocode) + 3;
-  char *tocode_conv;
-  bool tocode_usealloca = __libc_use_alloca (tocode_len);
-  if (tocode_usealloca)
-    tocode_conv = (char *) alloca (tocode_len);
-  else
-    {
-      tocode_conv = (char *) malloc (tocode_len);
-      if (tocode_conv == NULL)
-       return (iconv_t) -1;
-    }
-  strip (tocode_conv, tocode);
-  tocode = (tocode_conv[2] == '\0' && tocode[0] != '\0'
-           ? upstr (tocode_conv, tocode) : tocode_conv);
+  __gconv_t cd;
+  struct gconv_spec conv_spec;
 
-  size_t fromcode_len = strlen (fromcode) + 3;
-  char *fromcode_conv;
-  bool fromcode_usealloca = __libc_use_alloca (fromcode_len);
-  if (fromcode_usealloca)
-    fromcode_conv = (char *) alloca (fromcode_len);
-  else
-    {
-      fromcode_conv = (char *) malloc (fromcode_len);
-      if (fromcode_conv == NULL)
-       {
-         if (! tocode_usealloca)
-           free (tocode_conv);
-         return (iconv_t) -1;
-       }
-    }
-  strip (fromcode_conv, fromcode);
-  fromcode = (fromcode_conv[2] == '\0' && fromcode[0] != '\0'
-             ? upstr (fromcode_conv, fromcode) : fromcode_conv);
+  if (__gconv_create_spec (&conv_spec, fromcode, tocode) == NULL)
+    return (iconv_t) -1;
 
-  __gconv_t cd;
-  int res = __gconv_open (tocode, fromcode, &cd, 0);
+  int res = __gconv_open (&conv_spec, &cd, 0);
 
-  if (! fromcode_usealloca)
-    free (fromcode_conv);
-  if (! tocode_usealloca)
-    free (tocode_conv);
+  gconv_destroy_spec (&conv_spec);
 
   if (__builtin_expect (res, __GCONV_OK) != __GCONV_OK)
     {
index 9709e4a70188df9833a99af109490c93845981a6..b4334faa57a92b4aedec81c166e84e6c37f7c9ba 100644 (file)
@@ -39,6 +39,7 @@
 #include <gconv_int.h>
 #include "iconv_prog.h"
 #include "iconvconfig.h"
+#include "gconv_charset.h"
 
 /* Get libc version number.  */
 #include "../version.h"
@@ -118,8 +119,7 @@ main (int argc, char *argv[])
 {
   int status = EXIT_SUCCESS;
   int remaining;
-  iconv_t cd;
-  const char *orig_to_code;
+  __gconv_t cd;
   struct charmap_t *from_charmap = NULL;
   struct charmap_t *to_charmap = NULL;
 
@@ -139,39 +139,6 @@ main (int argc, char *argv[])
       exit (EXIT_SUCCESS);
     }
 
-  /* If we have to ignore errors make sure we use the appropriate name for
-     the to-character-set.  */
-  orig_to_code = to_code;
-  if (omit_invalid)
-    {
-      const char *errhand = strchrnul (to_code, '/');
-      int nslash = 2;
-      char *newp;
-      char *cp;
-
-      if (*errhand == '/')
-       {
-         --nslash;
-         errhand = strchrnul (errhand + 1, '/');
-
-         if (*errhand == '/')
-           {
-             --nslash;
-             errhand = strchr (errhand, '\0');
-           }
-       }
-
-      newp = (char *) alloca (errhand - to_code + nslash + 7 + 1);
-      cp = mempcpy (newp, to_code, errhand - to_code);
-      while (nslash-- > 0)
-       *cp++ = '/';
-      if (cp[-1] != '/')
-       *cp++ = ',';
-      memcpy (cp, "IGNORE", sizeof ("IGNORE"));
-
-      to_code = newp;
-    }
-
   /* POSIX 1003.2b introduces a silly thing: the arguments to -t anf -f
      can be file names of charmaps.  In this case iconv will have to read
      those charmaps and use them to do the conversion.  But there are
@@ -184,10 +151,10 @@ main (int argc, char *argv[])
        file.  */
     from_charmap = charmap_read (from_code, /*0, 1*/1, 0, 0, 0);
 
-  if (strchr (orig_to_code, '/') != NULL)
+  if (strchr (to_code, '/') != NULL)
     /* The to-name might be a charmap file name.  Try reading the
        file.  */
-    to_charmap = charmap_read (orig_to_code, /*0, 1,*/1, 0, 0, 0);
+    to_charmap = charmap_read (to_code, /*0, 1,*/1, 0, 0, 0);
 
 
   /* At this point we have to handle two cases.  The first one is
@@ -201,9 +168,25 @@ main (int argc, char *argv[])
                                 argc, remaining, argv, output_file);
   else
     {
+      struct gconv_spec conv_spec;
+      int res;
+
+      if (__gconv_create_spec (&conv_spec, from_code, to_code) == NULL)
+        {
+          error (EXIT_FAILURE, errno,
+                 _("failed to start conversion processing"));
+          exit (1);
+        }
+
+      if (omit_invalid)
+        conv_spec.ignore = true;
+
       /* Let's see whether we have these coded character sets.  */
-      cd = iconv_open (to_code, from_code);
-      if (cd == (iconv_t) -1)
+      res = __gconv_open (&conv_spec, &cd, 0);
+
+      gconv_destroy_spec (&conv_spec);
+
+      if (res != __GCONV_OK)
        {
          if (errno == EINVAL)
            {
@@ -221,7 +204,7 @@ main (int argc, char *argv[])
              const char *from_pretty =
                (from_code[0] ? from_code : nl_langinfo (CODESET));
              const char *to_pretty =
-               (orig_to_code[0] ? orig_to_code : nl_langinfo (CODESET));
+               (to_code[0] ? to_code : nl_langinfo (CODESET));
 
              if (from_wrong)
                {
diff --git a/iconv/tst-iconv-opt.c b/iconv/tst-iconv-opt.c
new file mode 100644 (file)
index 0000000..669d812
--- /dev/null
@@ -0,0 +1,347 @@
+/* Test iconv's TRANSLIT and IGNORE option handling
+
+   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 <iconv.h>
+#include <locale.h>
+#include <errno.h>
+#include <string.h>
+#include <support/support.h>
+#include <support/check.h>
+
+
+/* Run one iconv test.  Arguments:
+   to: destination character set and options
+   from: source character set
+   input: input string to be converted
+   exp_in: expected number of bytes consumed
+   exp_ret: expected return value (error or number of irreversible conversions)
+   exp_out: expected output string
+   exp_err: expected value of `errno' after iconv returns.  */
+static void
+test_iconv (const char *to, const char *from, char *input, size_t exp_in,
+            size_t exp_ret, const char *exp_out, int exp_err)
+{
+  iconv_t cd;
+  char outbuf[500];
+  size_t inlen, outlen;
+  char *inptr, *outptr;
+  size_t n;
+
+  cd = iconv_open (to, from);
+  TEST_VERIFY (cd != (iconv_t) -1);
+
+  inlen = strlen (input);
+  outlen = sizeof (outbuf);
+  inptr = input;
+  outptr = outbuf;
+
+  errno = 0;
+  n = iconv (cd, &inptr, &inlen, &outptr, &outlen);
+
+  TEST_COMPARE (n, exp_ret);
+  TEST_VERIFY (inptr == input + exp_in);
+  TEST_COMPARE (errno, exp_err);
+  TEST_COMPARE_BLOB (outbuf, outptr - outbuf, exp_out, strlen (exp_out));
+  TEST_VERIFY (iconv_close (cd) == 0);
+}
+
+
+/* We test option parsing by converting UTF-8 inputs to ASCII under various
+   option combinations. The UTF-8 inputs fall into three categories:
+   - ASCII-only,
+   - non-ASCII,
+   - non-ASCII with invalid UTF-8 characters.  */
+
+/* 1.  */
+char ascii[] = "Just some ASCII text";
+
+/* 2. Valid UTF-8 input and some corresponding expected outputs with various
+   options.  The two non-ASCII characters below are accented alphabets:
+   an `a' then an `o'.  */
+char utf8[] = "UTF-8 text with \u00E1 couple \u00F3f non-ASCII characters";
+char u2a[] = "UTF-8 text with ";
+char u2a_translit[] = "UTF-8 text with a couple of non-ASCII characters";
+char u2a_ignore[] = "UTF-8 text with  couple f non-ASCII characters";
+
+/* 3. Invalid UTF-8 input and some corresponding expected outputs.  \xff is
+   invalid UTF-8. It's followed by some valid but non-ASCII UTF-8.  */
+char iutf8[] = "Invalid UTF-8 \xff\u27E6text\u27E7";
+char iu2a[] = "Invalid UTF-8 ";
+char iu2a_ignore[] = "Invalid UTF-8 text";
+char iu2a_both[] = "Invalid UTF-8 [|text|]";
+
+/* 4. Another invalid UTF-8 input and corresponding expected outputs. This time
+   the valid non-ASCII UTF-8 characters appear before the invalid \xff.  */
+char jutf8[] = "Invalid \u27E6UTF-8\u27E7 \xfftext";
+char ju2a[] = "Invalid ";
+char ju2a_translit[] = "Invalid [|UTF-8|] ";
+char ju2a_ignore[] = "Invalid UTF-8 text";
+char ju2a_both[] = "Invalid [|UTF-8|] text";
+
+/* We also test option handling for character set names that have the form
+   "A/B".  In this test, we test conversions "ISO-10646/UTF-8", and either
+   ISO-8859-1 or ASCII.  */
+
+/* 5. Accented 'A' and 'a' characters in ISO-8859-1 and UTF-8, and an
+   equivalent ASCII transliteration.  */
+char iso8859_1_a[] = {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, /* Accented A's.  */
+                      0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, /* Accented a's.  */
+                      0x00};
+char utf8_a[] = "\u00C0\u00C1\u00C2\u00C3\u00C4\u00C5"
+                "\u00E0\u00E1\u00E2\u00E3\u00E4\u00E5";
+char ascii_a[] = "AAAAAAaaaaaa";
+
+/* 6. An invalid ASCII string where [0] is invalid and [1] is '~'.  */
+char iascii [] = {0x80, '~', '\0'};
+char empty[] = "";
+char ia2u_ignore[] = "~";
+
+static int
+do_test (void)
+{
+  xsetlocale (LC_ALL, "en_US.UTF-8");
+
+
+  /* 0. iconv_open should gracefully fail for invalid character sets.  */
+
+  TEST_VERIFY (iconv_open ("INVALID", "UTF-8") == (iconv_t) -1);
+  TEST_VERIFY (iconv_open ("UTF-8", "INVALID") == (iconv_t) -1);
+  TEST_VERIFY (iconv_open ("INVALID", "INVALID") == (iconv_t) -1);
+
+
+  /* 1. ASCII-only UTF-8 input should convert to ASCII with no changes:  */
+
+  test_iconv ("ASCII", "UTF-8", ascii, strlen (ascii), 0, ascii, 0);
+  test_iconv ("ASCII//", "UTF-8", ascii, strlen (ascii), 0, ascii, 0);
+  test_iconv ("ASCII//TRANSLIT", "UTF-8", ascii, strlen (ascii), 0, ascii, 0);
+  test_iconv ("ASCII//TRANSLIT//", "UTF-8", ascii, strlen (ascii), 0, ascii,
+              0);
+  test_iconv ("ASCII//IGNORE", "UTF-8", ascii, strlen (ascii), 0, ascii, 0);
+  test_iconv ("ASCII//IGNORE//", "UTF-8", ascii, strlen (ascii), 0, ascii, 0);
+
+
+  /* 2. Valid UTF-8 input with non-ASCII characters:  */
+
+  /* EILSEQ when converted to ASCII.  */
+  test_iconv ("ASCII", "UTF-8", utf8, strlen (u2a), (size_t) -1, u2a, EILSEQ);
+
+  /* Converted without error with TRANSLIT enabled.  */
+  test_iconv ("ASCII//TRANSLIT", "UTF-8", utf8, strlen (utf8), 2, u2a_translit,
+              0);
+
+  /* EILSEQ with IGNORE enabled.  Non-ASCII chars dropped from output.  */
+  test_iconv ("ASCII//IGNORE", "UTF-8", utf8, strlen (utf8), (size_t) -1,
+              u2a_ignore, EILSEQ);
+
+  /* With TRANSLIT and IGNORE enabled, transliterated without error.  We test
+     four combinations.  */
+
+  test_iconv ("ASCII//TRANSLIT,IGNORE", "UTF-8", utf8, strlen (utf8), 2,
+              u2a_translit, 0);
+  test_iconv ("ASCII//TRANSLIT//IGNORE", "UTF-8", utf8, strlen (utf8), 2,
+              u2a_translit, 0);
+  test_iconv ("ASCII//IGNORE,TRANSLIT", "UTF-8", utf8, strlen (utf8), 2,
+              u2a_translit, 0);
+  /* Due to bug 19519, iconv was ignoring TRANSLIT for the following input.  */
+  test_iconv ("ASCII//IGNORE//TRANSLIT", "UTF-8", utf8, strlen (utf8), 2,
+              u2a_translit, 0);
+
+  /* Misspellings of TRANSLIT and IGNORE are ignored, but conversion still
+     works while respecting any other correctly spelled options.  */
+
+  test_iconv ("ASCII//T", "UTF-8", utf8, strlen (u2a), (size_t) -1, u2a,
+              EILSEQ);
+  test_iconv ("ASCII//TRANSLITERATE", "UTF-8", utf8, strlen (u2a), (size_t) -1,
+              u2a, EILSEQ);
+  test_iconv ("ASCII//I", "UTF-8", utf8, strlen (u2a), (size_t) -1, u2a,
+              EILSEQ);
+  test_iconv ("ASCII//IGNORED", "UTF-8", utf8, strlen (u2a), (size_t) -1, u2a,
+              EILSEQ);
+  test_iconv ("ASCII//TRANSLITERATE//IGNORED", "UTF-8", utf8, strlen (u2a),
+              (size_t) -1, u2a, EILSEQ);
+  test_iconv ("ASCII//IGNORED,TRANSLITERATE", "UTF-8", utf8, strlen (u2a),
+              (size_t) -1, u2a, EILSEQ);
+  test_iconv ("ASCII//T//I", "UTF-8", utf8, strlen (u2a), (size_t) -1, u2a,
+              EILSEQ);
+
+  test_iconv ("ASCII//TRANSLIT//I", "UTF-8", utf8, strlen (utf8), 2,
+              u2a_translit, 0);
+  /* Due to bug 19519, iconv was ignoring TRANSLIT for the following input.  */
+  test_iconv ("ASCII//I//TRANSLIT", "UTF-8", utf8, strlen (utf8), 2,
+              u2a_translit, 0);
+  test_iconv ("ASCII//IGNORED,TRANSLIT", "UTF-8", utf8, strlen (utf8), 2,
+              u2a_translit, 0);
+  test_iconv ("ASCII//TRANSLIT,IGNORED", "UTF-8", utf8, strlen (utf8), 2,
+              u2a_translit, 0);
+
+  test_iconv ("ASCII//IGNORE,T", "UTF-8", utf8, strlen (utf8), (size_t) -1,
+              u2a_ignore, EILSEQ);
+  test_iconv ("ASCII//T,IGNORE", "UTF-8", utf8, strlen (utf8), (size_t) -1,
+              u2a_ignore, EILSEQ);
+  /* Due to bug 19519, iconv was ignoring IGNORE for the following input.  */
+  test_iconv ("ASCII//TRANSLITERATE//IGNORE", "UTF-8", utf8, strlen (utf8),
+              (size_t) -1, u2a_ignore, EILSEQ);
+  test_iconv ("ASCII//IGNORE//TRANSLITERATE", "UTF-8", utf8, strlen (utf8),
+              (size_t) -1, u2a_ignore, EILSEQ);
+
+
+  /* 3. Invalid UTF-8 followed by some valid non-ASCII UTF-8 characters:  */
+
+  /* EILSEQ; output is truncated at the first invalid UTF-8 character.  */
+  test_iconv ("ASCII", "UTF-8", iutf8, strlen (iu2a), (size_t) -1, iu2a,
+              EILSEQ);
+
+  /* With TRANSLIT enabled: EILSEQ; output still truncated at the first invalid
+     UTF-8 character.  */
+  test_iconv ("ASCII//TRANSLIT", "UTF-8", iutf8, strlen (iu2a), (size_t) -1,
+              iu2a, EILSEQ);
+
+  /* With IGNORE enabled: EILSEQ; output omits invalid UTF-8 characters and
+     valid UTF-8 non-ASCII characters.  */
+  test_iconv ("ASCII//IGNORE", "UTF-8", iutf8, strlen (iutf8), (size_t) -1,
+              iu2a_ignore, EILSEQ);
+
+  /* With TRANSLIT and IGNORE enabled, output omits only invalid UTF-8
+     characters and transliterates valid non-ASCII UTF-8 characters.  We test
+     four combinations.  */
+
+  test_iconv ("ASCII//TRANSLIT,IGNORE", "UTF-8", iutf8, strlen (iutf8), 2,
+              iu2a_both, 0);
+  /* Due to bug 19519, iconv was ignoring IGNORE for the following input.  */
+  test_iconv ("ASCII//TRANSLIT//IGNORE", "UTF-8", iutf8, strlen (iutf8), 2,
+              iu2a_both, 0);
+  test_iconv ("ASCII//IGNORE,TRANSLIT", "UTF-8", iutf8, strlen (iutf8), 2,
+              iu2a_both, 0);
+  /* Due to bug 19519, iconv was ignoring TRANSLIT for the following input.  */
+  test_iconv ("ASCII//IGNORE//TRANSLIT", "UTF-8", iutf8, strlen (iutf8), 2,
+              iu2a_both, 0);
+
+
+  /* 4. Invalid UTF-8 with valid non-ASCII UTF-8 chars appearing first:  */
+
+  /* EILSEQ; output is truncated at the first non-ASCII character.  */
+  test_iconv ("ASCII", "UTF-8", jutf8, strlen (ju2a), (size_t) -1, ju2a,
+              EILSEQ);
+
+  /* With TRANSLIT enabled: EILSEQ; output now truncated at the first invalid
+     UTF-8 character.  */
+  test_iconv ("ASCII//TRANSLIT", "UTF-8", jutf8, strlen (jutf8) - 5,
+              (size_t) -1, ju2a_translit, EILSEQ);
+  test_iconv ("ASCII//translit", "UTF-8", jutf8, strlen (jutf8) - 5,
+              (size_t) -1, ju2a_translit, EILSEQ);
+
+  /* With IGNORE enabled: EILSEQ; output omits invalid UTF-8 characters and
+     valid UTF-8 non-ASCII characters.  */
+  test_iconv ("ASCII//IGNORE", "UTF-8", jutf8, strlen (jutf8), (size_t) -1,
+              ju2a_ignore, EILSEQ);
+  test_iconv ("ASCII//ignore", "UTF-8", jutf8, strlen (jutf8), (size_t) -1,
+              ju2a_ignore, EILSEQ);
+
+  /* With TRANSLIT and IGNORE enabled, output omits only invalid UTF-8
+     characters and transliterates valid non-ASCII UTF-8 characters.  We test
+     several combinations.  */
+
+  test_iconv ("ASCII//TRANSLIT,IGNORE", "UTF-8", jutf8, strlen (jutf8), 2,
+              ju2a_both, 0);
+  /* Due to bug 19519, iconv was ignoring IGNORE for the following input.  */
+  test_iconv ("ASCII//TRANSLIT//IGNORE", "UTF-8", jutf8, strlen (jutf8), 2,
+              ju2a_both, 0);
+  test_iconv ("ASCII//IGNORE,TRANSLIT", "UTF-8", jutf8, strlen (jutf8), 2,
+              ju2a_both, 0);
+  /* Due to bug 19519, iconv was ignoring TRANSLIT for the following input.  */
+  test_iconv ("ASCII//IGNORE//TRANSLIT", "UTF-8", jutf8, strlen (jutf8), 2,
+              ju2a_both, 0);
+  test_iconv ("ASCII//translit,ignore", "UTF-8", jutf8, strlen (jutf8), 2,
+              ju2a_both, 0);
+  /* Trailing whitespace and separators should be ignored.  */
+  test_iconv ("ASCII//IGNORE,TRANSLIT ", "UTF-8", jutf8, strlen (jutf8), 2,
+              ju2a_both, 0);
+  test_iconv ("ASCII//IGNORE,TRANSLIT/", "UTF-8", jutf8, strlen (jutf8), 2,
+              ju2a_both, 0);
+  test_iconv ("ASCII//IGNORE,TRANSLIT//", "UTF-8", jutf8, strlen (jutf8), 2,
+              ju2a_both, 0);
+  test_iconv ("ASCII//IGNORE,TRANSLIT,", "UTF-8", jutf8, strlen (jutf8), 2,
+              ju2a_both, 0);
+  test_iconv ("ASCII//IGNORE,TRANSLIT,,", "UTF-8", jutf8, strlen (jutf8), 2,
+              ju2a_both, 0);
+  test_iconv ("ASCII//IGNORE,TRANSLIT /,", "UTF-8", jutf8, strlen (jutf8), 2,
+              ju2a_both, 0);
+
+  /* TRANSLIT or IGNORE suffixes in fromcode should be ignored.  */
+  test_iconv ("ASCII", "UTF-8//TRANSLIT", jutf8, strlen (ju2a), (size_t) -1,
+              ju2a, EILSEQ);
+  test_iconv ("ASCII", "UTF-8//IGNORE", jutf8, strlen (ju2a), (size_t) -1,
+              ju2a, EILSEQ);
+  test_iconv ("ASCII", "UTF-8//TRANSLIT,IGNORE", jutf8, strlen (ju2a),
+              (size_t) -1, ju2a, EILSEQ);
+
+
+  /* 5. Charset names of the form "A/B/":  */
+
+  /* ISO-8859-1 is converted to UTF-8 without needing transliteration.  */
+  test_iconv ("ISO-10646/UTF-8", "ISO-8859-1", iso8859_1_a,
+              strlen (iso8859_1_a), 0, utf8_a, 0);
+  test_iconv ("ISO-10646/UTF-8/", "ISO-8859-1", iso8859_1_a,
+              strlen (iso8859_1_a), 0, utf8_a, 0);
+  test_iconv ("ISO-10646/UTF-8/IGNORE", "ISO-8859-1", iso8859_1_a,
+              strlen (iso8859_1_a), 0, utf8_a, 0);
+  test_iconv ("ISO-10646/UTF-8//IGNORE", "ISO-8859-1", iso8859_1_a,
+              strlen (iso8859_1_a), 0, utf8_a, 0);
+  test_iconv ("ISO-10646/UTF-8/TRANSLIT", "ISO-8859-1", iso8859_1_a,
+              strlen (iso8859_1_a), 0, utf8_a, 0);
+  test_iconv ("ISO-10646/UTF-8//TRANSLIT", "ISO-8859-1", iso8859_1_a,
+              strlen (iso8859_1_a), 0, utf8_a, 0);
+  test_iconv ("ISO-10646/UTF-8//TRANSLIT/IGNORE", "ISO-8859-1", iso8859_1_a,
+              strlen (iso8859_1_a), 0, utf8_a, 0);
+  test_iconv ("ISO-10646/UTF-8//TRANSLIT//IGNORE", "ISO-8859-1", iso8859_1_a,
+              strlen (iso8859_1_a), 0, utf8_a, 0);
+  test_iconv ("ISO-10646/UTF-8/TRANSLIT,IGNORE", "ISO-8859-1", iso8859_1_a,
+              strlen (iso8859_1_a), 0, utf8_a, 0);
+
+  /* UTF-8 with accented A's is converted to ASCII with transliteration.  */
+  test_iconv ("ASCII", "ISO-10646/UTF-8", utf8_a,
+              0, (size_t) -1, empty, EILSEQ);
+  test_iconv ("ASCII//IGNORE", "ISO-10646/UTF-8", utf8_a,
+              strlen (utf8_a), (size_t) -1, empty, EILSEQ);
+  test_iconv ("ASCII//TRANSLIT", "ISO-10646/UTF-8", utf8_a,
+              strlen (utf8_a), 12, ascii_a, 0);
+
+  /* Invalid ASCII is converted to UTF-8 only with IGNORE.  */
+  test_iconv ("ISO-10646/UTF-8", "ASCII", iascii, strlen (empty), (size_t) -1,
+              empty, EILSEQ);
+  test_iconv ("ISO-10646/UTF-8/TRANSLIT", "ASCII", iascii, strlen (empty),
+              (size_t) -1, empty, EILSEQ);
+  test_iconv ("ISO-10646/UTF-8/IGNORE", "ASCII", iascii, strlen (iascii),
+              (size_t) -1, ia2u_ignore, EILSEQ);
+  test_iconv ("ISO-10646/UTF-8/TRANSLIT,IGNORE", "ASCII", iascii,
+              strlen (iascii), (size_t) -1, ia2u_ignore, EILSEQ);
+  /* Due to bug 19519, iconv was ignoring IGNORE for the following three
+     inputs: */
+  test_iconv ("ISO-10646/UTF-8/TRANSLIT/IGNORE", "ASCII", iascii,
+              strlen (iascii), (size_t) -1, ia2u_ignore, EILSEQ);
+  test_iconv ("ISO-10646/UTF-8//TRANSLIT,IGNORE", "ASCII", iascii,
+              strlen (iascii), (size_t) -1, ia2u_ignore, EILSEQ);
+  test_iconv ("ISO-10646/UTF-8//TRANSLIT//IGNORE", "ASCII", iascii,
+              strlen (iascii), (size_t) -1, ia2u_ignore, EILSEQ);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/iconv/tst-iconv_prog.sh b/iconv/tst-iconv_prog.sh
new file mode 100644 (file)
index 0000000..8298136
--- /dev/null
@@ -0,0 +1,280 @@
+#!/bin/bash
+# Test for some known iconv(1) hangs from bug 19519, and miscellaneous
+# iconv(1) program error conditions.
+# 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/>.
+
+codir=$1
+test_wrapper_env="$2"
+run_program_env="$3"
+
+# We have to have some directories in the library path.
+LIBPATH=$codir:$codir/iconvdata
+
+# How the start the iconv(1) program.  $from is not defined/expanded yet.
+ICONV='
+$codir/elf/ld.so --library-path $LIBPATH --inhibit-rpath ${from}.so
+$codir/iconv/iconv_prog
+'
+ICONV="$test_wrapper_env $run_program_env $ICONV"
+
+# List of known hangs;
+# Gathered by running an exhaustive 2 byte input search against glibc-2.28
+hangarray=(
+"\x00\x23;-c;ANSI_X3.110;UTF-8//TRANSLIT//IGNORE"
+"\x00\xa1;-c;ARMSCII-8;UTF-8//TRANSLIT//IGNORE"
+"\x00\xa1;-c;ASMO_449;UTF-8//TRANSLIT//IGNORE"
+"\x00\x81;-c;BIG5;UTF-8//TRANSLIT//IGNORE"
+"\x00\xff;-c;BIG5HKSCS;UTF-8//TRANSLIT//IGNORE"
+"\x00\xff;-c;BRF;UTF-8//TRANSLIT//IGNORE"
+"\x00\xff;-c;BS_4730;UTF-8//TRANSLIT//IGNORE"
+"\x00\x81;-c;CP1250;UTF-8//TRANSLIT//IGNORE"
+"\x00\x98;-c;CP1251;UTF-8//TRANSLIT//IGNORE"
+"\x00\x81;-c;CP1252;UTF-8//TRANSLIT//IGNORE"
+"\x00\x81;-c;CP1253;UTF-8//TRANSLIT//IGNORE"
+"\x00\x81;-c;CP1254;UTF-8//TRANSLIT//IGNORE"
+"\x00\x81;-c;CP1255;UTF-8//TRANSLIT//IGNORE"
+"\x00\x81;-c;CP1257;UTF-8//TRANSLIT//IGNORE"
+"\x00\x81;-c;CP1258;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;CP932;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;CSA_Z243.4-1985-1;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;CSA_Z243.4-1985-2;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;DEC-MCS;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;DIN_66003;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;DS_2089;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;EBCDIC-AT-DE;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;EBCDIC-AT-DE-A;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;EBCDIC-CA-FR;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;EBCDIC-DK-NO;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;EBCDIC-DK-NO-A;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;EBCDIC-ES;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;EBCDIC-ES-A;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;EBCDIC-ES-S;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;EBCDIC-FI-SE;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;EBCDIC-FI-SE-A;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;EBCDIC-FR;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;EBCDIC-IS-FRISS;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;EBCDIC-IT;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;EBCDIC-PT;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;EBCDIC-UK;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;EBCDIC-US;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;ES;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;ES2;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;EUC-CN;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;EUC-JISX0213;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;EUC-JP;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;EUC-JP-MS;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;EUC-KR;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;EUC-TW;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;GB18030;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;GB_1988-80;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;GBK;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;GOST_19768-74;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;GREEK7;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;GREEK7-OLD;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;GREEK-CCITT;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;HP-GREEK8;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;HP-ROMAN8;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;HP-ROMAN9;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;HP-THAI8;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;HP-TURKISH8;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;IBM038;UTF-8//TRANSLIT//IGNORE"
+"\x00\x80;-c;IBM1004;UTF-8//TRANSLIT//IGNORE"
+"\x00\xff;-c;IBM1008;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;IBM1046;UTF-8//TRANSLIT//IGNORE"
+"\x00\x51;-c;IBM1132;UTF-8//TRANSLIT//IGNORE"
+"\x00\xa0;-c;IBM1133;UTF-8//TRANSLIT//IGNORE"
+"\x00\xce;-c;IBM1137;UTF-8//TRANSLIT//IGNORE"
+"\x00\x80;-c;IBM1161;UTF-8//TRANSLIT//IGNORE"
+"\x00\xdb;-c;IBM1162;UTF-8//TRANSLIT//IGNORE"
+"\x00\x70;-c;IBM12712;UTF-8//TRANSLIT//IGNORE"
+# These are known hangs that are yet to be fixed:
+# "\x00\x0f;-c;IBM1364;UTF-8"
+# "\x00\x0f;-c;IBM1371;UTF-8"
+# "\x00\x0f;-c;IBM1388;UTF-8"
+# "\x00\x0f;-c;IBM1390;UTF-8"
+# "\x00\x0f;-c;IBM1399;UTF-8"
+"\x00\x53;-c;IBM16804;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;IBM274;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;IBM275;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;IBM281;UTF-8//TRANSLIT//IGNORE"
+"\x00\x57;-c;IBM290;UTF-8//TRANSLIT//IGNORE"
+"\x00\x45;-c;IBM420;UTF-8//TRANSLIT//IGNORE"
+"\x00\x68;-c;IBM423;UTF-8//TRANSLIT//IGNORE"
+"\x00\x70;-c;IBM424;UTF-8//TRANSLIT//IGNORE"
+"\x00\x53;-c;IBM4517;UTF-8//TRANSLIT//IGNORE"
+"\x00\x53;-c;IBM4899;UTF-8//TRANSLIT//IGNORE"
+"\x00\xa5;-c;IBM4909;UTF-8//TRANSLIT//IGNORE"
+"\x00\xdc;-c;IBM4971;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;IBM803;UTF-8//TRANSLIT//IGNORE"
+"\x00\x91;-c;IBM851;UTF-8//TRANSLIT//IGNORE"
+"\x00\x9b;-c;IBM856;UTF-8//TRANSLIT//IGNORE"
+"\x00\xd5;-c;IBM857;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;IBM864;UTF-8//TRANSLIT//IGNORE"
+"\x00\x94;-c;IBM868;UTF-8//TRANSLIT//IGNORE"
+"\x00\x94;-c;IBM869;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;IBM874;UTF-8//TRANSLIT//IGNORE"
+"\x00\x6a;-c;IBM875;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;IBM880;UTF-8//TRANSLIT//IGNORE"
+"\x00\x80;-c;IBM891;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;IBM903;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;IBM904;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;IBM905;UTF-8//TRANSLIT//IGNORE"
+"\x00\x80;-c;IBM9066;UTF-8//TRANSLIT//IGNORE"
+"\x00\x48;-c;IBM918;UTF-8//TRANSLIT//IGNORE"
+"\x00\x57;-c;IBM930;UTF-8//TRANSLIT//IGNORE"
+"\x00\x80;-c;IBM932;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;IBM933;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;IBM935;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;IBM937;UTF-8//TRANSLIT//IGNORE"
+"\x00\x41;-c;IBM939;UTF-8//TRANSLIT//IGNORE"
+"\x00\x80;-c;IBM943;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;INIS;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;INIS-8;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;INIS-CYRILLIC;UTF-8//TRANSLIT//IGNORE"
+"\x00\xec;-c;ISIRI-3342;UTF-8//TRANSLIT//IGNORE"
+"\x00\xec;-c;ISO_10367-BOX;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;ISO-2022-CN;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;ISO-2022-CN-EXT;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;ISO-2022-JP;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;ISO-2022-JP-2;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;ISO-2022-JP-3;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;ISO-2022-KR;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;ISO_2033;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;ISO_5427;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;ISO_5427-EXT;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;ISO_5428;UTF-8//TRANSLIT//IGNORE"
+"\x00\xa4;-c;ISO_6937;UTF-8//TRANSLIT//IGNORE"
+"\x00\xa0;-c;ISO_6937-2;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;ISO-8859-11;UTF-8//TRANSLIT//IGNORE"
+"\x00\xa5;-c;ISO-8859-3;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;ISO-8859-6;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;ISO-8859-7;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;ISO-8859-8;UTF-8//TRANSLIT//IGNORE"
+"\x00\x80;-c;ISO-IR-197;UTF-8//TRANSLIT//IGNORE"
+"\x00\x80;-c;ISO-IR-209;UTF-8//TRANSLIT//IGNORE"
+"\x00\x80;-c;IT;UTF-8//TRANSLIT//IGNORE"
+"\x00\x80;-c;JIS_C6220-1969-RO;UTF-8//TRANSLIT//IGNORE"
+"\x00\x80;-c;JIS_C6229-1984-B;UTF-8//TRANSLIT//IGNORE"
+"\x00\x80;-c;JOHAB;UTF-8//TRANSLIT//IGNORE"
+"\x00\x80;-c;JUS_I.B1.002;UTF-8//TRANSLIT//IGNORE"
+"\x00\x80;-c;KOI-8;UTF-8//TRANSLIT//IGNORE"
+"\x00\x88;-c;KOI8-T;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;KSC5636;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;LATIN-GREEK;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;LATIN-GREEK-1;UTF-8//TRANSLIT//IGNORE"
+"\x00\xf6;-c;MAC-IS;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;MSZ_7795.3;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;NATS-DANO;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;NATS-SEFI;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;NC_NC00-10;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;NF_Z_62-010;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;NF_Z_62-010_1973;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;NS_4551-1;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;NS_4551-2;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;PT;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;PT2;UTF-8//TRANSLIT//IGNORE"
+"\x00\x98;-c;RK1048;UTF-8//TRANSLIT//IGNORE"
+"\x00\x98;-c;SEN_850200_B;UTF-8//TRANSLIT//IGNORE"
+"\x00\x98;-c;SEN_850200_C;UTF-8//TRANSLIT//IGNORE"
+"\x00\x80;-c;Shift_JISX0213;UTF-8//TRANSLIT//IGNORE"
+"\x00\x80;-c;SJIS;UTF-8//TRANSLIT//IGNORE"
+"\x00\x23;-c;T.61-8BIT;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;TIS-620;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;TSCII;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;UHC;UTF-8//TRANSLIT//IGNORE"
+"\x00\xd8;-c;UNICODE;UTF-8//TRANSLIT//IGNORE"
+"\x00\xdc;-c;UTF-16;UTF-8//TRANSLIT//IGNORE"
+"\xdc\x00;-c;UTF-16BE;UTF-8//TRANSLIT//IGNORE"
+"\x00\xdc;-c;UTF-16LE;UTF-8//TRANSLIT//IGNORE"
+"\xff\xff;-c;UTF-7;UTF-8//TRANSLIT//IGNORE"
+"\x00\x81;-c;WIN-SAMI-2;UTF-8//TRANSLIT//IGNORE"
+)
+
+# List of option combinations that *should* lead to an error
+errorarray=(
+# Converting from/to invalid character sets should cause error
+"\x00\x00;;INVALID;INVALID"
+"\x00\x00;;INVALID;UTF-8"
+"\x00\x00;;UTF-8;INVALID"
+)
+
+# Requires $twobyte input, $c flag, $from, and $to to be set; sets $ret
+execute_test ()
+{
+  eval PROG=\"$ICONV\"
+  echo -en "$twobyte" \
+    | timeout -k 4 3 $PROG $c -f $from -t "$to" &>/dev/null
+  ret=$?
+}
+
+check_hangtest_result ()
+{
+  if [ "$ret" -eq "124" ] || [ "$ret" -eq "137" ]; then # timeout/hang
+    result="HANG"
+  else
+    if [ "$ret" -eq "139" ]; then # segfault
+      result="SEGFAULT"
+    else
+      if [ "$ret" -gt "127" ]; then # unexpected error
+        result="UNEXPECTED"
+      else
+        result="OK"
+      fi
+    fi
+  fi
+
+  echo -n "$result: from: \"$from\", to: \"$to\","
+  echo    " input \"$twobyte\", flags \"$c\""
+
+  if [ "$result" != "OK" ]; then
+    exit 1
+  fi
+}
+
+for hangcommand in "${hangarray[@]}"; do
+  twobyte="$(echo "$hangcommand" | cut -d";" -f 1)"
+  c="$(echo "$hangcommand" | cut -d";" -f 2)"
+  from="$(echo "$hangcommand" | cut -d";" -f 3)"
+  to="$(echo "$hangcommand" | cut -d";" -f 4)"
+  execute_test
+  check_hangtest_result
+done
+
+check_errtest_result ()
+{
+  if [ "$ret" -eq "1" ]; then # we errored out as expected
+    result="PASS"
+  else
+    result="FAIL"
+  fi
+  echo -n "$result: from: \"$from\", to: \"$to\","
+  echo    " input \"$twobyte\", flags \"$c\", return code $ret"
+
+  if [ "$result" != "PASS" ]; then
+    exit 1
+  fi
+}
+
+for errorcommand in "${errorarray[@]}"; do
+  twobyte="$(echo "$errorcommand" | cut -d";" -f 1)"
+  c="$(echo "$errorcommand" | cut -d";" -f 2)"
+  from="$(echo "$errorcommand" | cut -d";" -f 3)"
+  to="$(echo "$errorcommand" | cut -d";" -f 4)"
+  execute_test
+  check_errtest_result
+done
index 0920ed642b43bbc6b462e1d7a66ae59455c84bda..d33f3a290e77527a01bd393e3f3f5b169b7e8b78 100644 (file)
@@ -4,6 +4,7 @@
 # ifndef _ISOMAC
 
 extern int __prctl (int __option, ...);
+libc_hidden_proto (__prctl)
 
 # endif /* !_ISOMAC */
 #endif
index 465c8df34ccfd8b698249af65999d7865f912143..2e7c662bc7865bfaa8f9d20f5408da044aef8129 100644 (file)
@@ -1119,11 +1119,16 @@ _nl_find_msg (struct loaded_l10nfile *domain_file,
                      outcharset = encoding;
 
 # ifdef _LIBC
-                     /* We always want to use transliteration.  */
-                     outcharset = norm_add_slashes (outcharset, "TRANSLIT");
-                     charset = norm_add_slashes (charset, "");
-                     int r = __gconv_open (outcharset, charset, &convd->conv,
-                                           GCONV_AVOID_NOCONV);
+
+                     struct gconv_spec conv_spec
+                       = { .fromcode = norm_add_slashes (charset, ""),
+                           .tocode = norm_add_slashes (outcharset, ""),
+                           /* We always want to use transliteration.  */
+                           .translit = true,
+                           .ignore = false
+                         };
+                     int r = __gconv_open (&conv_spec, &convd->conv,
+                                           GCONV_AVOID_NOCONV);
                      if (__builtin_expect (r != __GCONV_OK, 0))
                        {
                          /* If the output encoding is the same there is
index d0d89a149e5f4b33e31b55543fa5c84457f5057f..ba9377ed41c53f981153113422281ece25d94584 100644 (file)
@@ -92,7 +92,7 @@ day     "dimenge";/
         "diluns";/
         "dimars";/
         "dim<U00E8>cres";/
-        "dij<U00F3>us";/
+        "dij<U00F2>us";/
         "divendres";/
         "dissabte"
 abmon   "gen.";/
@@ -110,7 +110,7 @@ abmon   "gen.";/
 alt_mon "geni<U00E8>r";/
         "febri<U00E8>r";/
         "mar<U00E7>";/
-        "abrial";/
+        "abril";/
         "mai";/
         "junh";/
         "julhet";/
@@ -122,7 +122,7 @@ alt_mon "geni<U00E8>r";/
 mon     "de geni<U00E8>r";/
         "de febri<U00E8>r";/
         "de mar<U00E7>";/
-        "d<U2019>abrial";/
+        "d<U2019>abril";/
         "de mai";/
         "de junh";/
         "de julhet";/
index 0602a948959bbaf49996ebaaa540dcda90e321c9..fc1fd64b21f90dd809550abac7fb3627d321fca9 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);
index 5985b6744b9f7d49fbfda93ef8627d8a1add1b18..3496af40400079172def7b9dc41786e78e8db3b6 100644 (file)
@@ -644,6 +644,128 @@ ifneq ($(long-double-fcts),yes)
 # We won't compile the `long double' code at all.  Tell the `double' code
 # to define aliases for the `FUNCl' names.
 math-CPPFLAGS += -DNO_LONG_DOUBLE
+# GCC 10 diagnoses aliases with types conflicting with built-in
+# functions.
+CFLAGS-w_acos.c += -fno-builtin-acosl
+CFLAGS-w_acosh.c += -fno-builtin-acoshl
+CFLAGS-w_asin.c += -fno-builtin-asinl
+CFLAGS-s_asinh.c += -fno-builtin-asinhl
+CFLAGS-s_atan.c += -fno-builtin-atanl
+CFLAGS-w_atan2.c += -fno-builtin-atan2l
+CFLAGS-w_atanh.c += -fno-builtin-atanhl
+CFLAGS-s_cabs.c += -fno-builtin-cabsl
+CFLAGS-s_cacos.c += -fno-builtin-cacosl
+CFLAGS-s_cacosh.c += -fno-builtin-cacoshl
+CFLAGS-s_canonicalize.c += -fno-builtin-canonicalizel
+CFLAGS-s_carg.c += -fno-builtin-cargl
+CFLAGS-s_casin.c += -fno-builtin-casinl
+CFLAGS-s_casinh.c += -fno-builtin-casinhl
+CFLAGS-s_catan.c += -fno-builtin-catanl
+CFLAGS-s_catanh.c += -fno-builtin-catanhl
+CFLAGS-s_cbrt.c += -fno-builtin-cbrtl
+CFLAGS-s_ccos.c += -fno-builtin-ccosl
+CFLAGS-s_ccosh.c += -fno-builtin-ccoshl
+CFLAGS-s_ceil.c += -fno-builtin-ceill
+CFLAGS-s_cexp.c += -fno-builtin-cexpl
+CFLAGS-s_cimag.c += -fno-builtin-cimagl
+CFLAGS-s_clog.c += -fno-builtin-clogl
+CFLAGS-s_clog10.c += -fno-builtin-clog10l
+CFLAGS-s_conj.c += -fno-builtin-conjl
+CFLAGS-s_copysign.c += -fno-builtin-copysignl
+CFLAGS-s_cos.c += -fno-builtin-cosl
+CFLAGS-w_cosh.c += -fno-builtin-coshl
+CFLAGS-s_cpow.c += -fno-builtin-cpowl
+CFLAGS-s_cproj.c += -fno-builtin-cprojl
+CFLAGS-s_creal.c += -fno-builtin-creall
+CFLAGS-s_csin.c += -fno-builtin-csinl
+CFLAGS-s_csinh.c += -fno-builtin-csinhl
+CFLAGS-s_csqrt.c += -fno-builtin-csqrtl
+CFLAGS-s_ctan.c += -fno-builtin-ctanl
+CFLAGS-s_ctanh.c += -fno-builtin-ctanhl
+CFLAGS-s_dadd.c += -fno-builtin-daddl
+CFLAGS-s_ddiv.c += -fno-builtin-ddivl
+CFLAGS-s_dmul.c += -fno-builtin-dmull
+CFLAGS-s_dsub.c += -fno-builtin-dsubl
+CFLAGS-s_erf.c += -fno-builtin-erfl
+CFLAGS-s_erfc.c += -fno-builtin-erfcl
+CFLAGS-e_exp.c += -fno-builtin-expl
+CFLAGS-w_exp10.c += -fno-builtin-exp10l
+CFLAGS-e_exp2.c += -fno-builtin-exp2l
+CFLAGS-s_expm1.c += -fno-builtin-expm1l
+CFLAGS-s_fabs.c += -fno-builtin-fabsl
+CFLAGS-s_fadd.c += -fno-builtin-faddl
+CFLAGS-s_fdim.c += -fno-builtin-fdiml
+CFLAGS-s_fdiv.c += -fno-builtin-fdivl
+CFLAGS-s_finite.c += -fno-builtin-finitel
+CFLAGS-s_floor.c += -fno-builtin-floorl
+CFLAGS-s_fma.c += -fno-builtin-fmal
+CFLAGS-s_fmax.c += -fno-builtin-fmaxl
+CFLAGS-s_fmaxmag.c += -fno-builtin-fmaxmagl
+CFLAGS-s_fmin.c += -fno-builtin-fminl
+CFLAGS-s_fminmag.c += -fno-builtin-fminmagl
+CFLAGS-w_fmod.c += -fno-builtin-fmodl
+CFLAGS-s_fmul.c += -fno-builtin-fmull
+CFLAGS-s_frexp.c += -fno-builtin-frexpl
+CFLAGS-s_fromfp.c += -fno-builtin-fromfpl
+CFLAGS-s_fromfpx.c += -fno-builtin-fromfpxl
+CFLAGS-s_fsub.c += -fno-builtin-fsubl
+CFLAGS-s_gamma.c += -fno-builtin-gammal
+CFLAGS-s_getpayload.c += -fno-builtin-getpayloadl
+CFLAGS-w_hypot.c += -fno-builtin-hypotl
+CFLAGS-w_ilogb.c += -fno-builtin-ilogbl
+CFLAGS-s_isinf.c += -fno-builtin-isinfl
+CFLAGS-s_isnan.c += -fno-builtin-isnanl
+CFLAGS-w_j0.c += -fno-builtin-j0l
+CFLAGS-w_j1.c += -fno-builtin-j1l
+CFLAGS-w_jn.c += -fno-builtin-jnl
+CFLAGS-s_ldexp.c += -fno-builtin-ldexpl
+CFLAGS-w_lgamma.c += -fno-builtin-lgammal
+CFLAGS-w_lgamma_r.c += -fno-builtin-lgammal_r
+CFLAGS-w_llogb.c += -fno-builtin-llogbl
+CFLAGS-s_llrint.c += -fno-builtin-llrintl
+CFLAGS-s_llround.c += -fno-builtin-llroundl
+CFLAGS-e_log.c += -fno-builtin-logl
+CFLAGS-w_log10.c += -fno-builtin-log10l
+CFLAGS-w_log1p.c += -fno-builtin-log1pl
+CFLAGS-e_log2.c += -fno-builtin-log2l
+CFLAGS-s_logb.c += -fno-builtin-logbl
+CFLAGS-s_lrint.c += -fno-builtin-lrintl
+CFLAGS-s_lround.c += -fno-builtin-lroundl
+CFLAGS-s_modf.c += -fno-builtin-modfl
+CFLAGS-s_nan.c += -fno-builtin-nanl
+CFLAGS-s_nearbyint.c += -fno-builtin-nearbyintl
+CFLAGS-s_nextafter.c += -fno-builtin-nextafterl
+CFLAGS-s_nextdown.c += -fno-builtin-nextdownl
+CFLAGS-s_nexttoward.c += -fno-builtin-nexttoward -fno-builtin-nexttowardl
+CFLAGS-s_nexttowardf.c += -fno-builtin-nexttowardf
+CFLAGS-s_nextup.c += -fno-builtin-nextupl
+CFLAGS-e_pow.c += -fno-builtin-powl
+CFLAGS-w_remainder.c += -fno-builtin-remainderl -fno-builtin-dreml
+CFLAGS-s_remquo.c += -fno-builtin-remquol
+CFLAGS-s_rint.c += -fno-builtin-rintl
+CFLAGS-s_round.c += -fno-builtin-roundl
+CFLAGS-s_roundeven.c += -fno-builtin-roundevenl
+CFLAGS-w_scalb.c += -fno-builtin-scalbl
+CFLAGS-w_scalbln.c += -fno-builtin-scalblnl
+CFLAGS-s_scalbn.c += -fno-builtin-scalbnl
+CFLAGS-s_setpayload.c += -fno-builtin-setpayloadl
+CFLAGS-s_setpayloadsig.c += -fno-builtin-setpayloadsigl
+CFLAGS-s_significand.c += -fno-builtin-significandl
+CFLAGS-s_sin.c += -fno-builtin-sinl
+CFLAGS-s_sincos.c += -fno-builtin-sincosl
+CFLAGS-w_sinh.c += -fno-builtin-sinhl
+CFLAGS-w_sqrt.c += -fno-builtin-sqrtl
+CFLAGS-s_tan.c += -fno-builtin-tanl
+CFLAGS-s_tanh.c += -fno-builtin-tanhl
+CFLAGS-w_tgamma.c += -fno-builtin-tgammal
+CFLAGS-s_totalorder.c += -fno-builtin-totalorderl
+CFLAGS-s_totalordermag.c += -fno-builtin-totalordermagl
+CFLAGS-s_trunc.c += -fno-builtin-truncl
+CFLAGS-s_ufromfp.c += -fno-builtin-ufromfpl
+CFLAGS-s_ufromfpx.c += -fno-builtin-ufromfpxl
+CFLAGS-s_y0.c += -fno-builtin-y0l
+CFLAGS-s_y1.c += -fno-builtin-y1l
+CFLAGS-s_yn.c += -fno-builtin-ynl
 endif
 
 # These files quiet sNaNs in a way that is optimized away without
index e0465980c7bffc61db4a76080f5d7264b96ea71c..e167e199eb626786f08209c554beae2e82ffa521 100644 (file)
@@ -87,7 +87,7 @@ tests := tst-dirname tst-tsearch tst-fdset tst-mntent tst-hsearch \
         tst-preadvwritev tst-preadvwritev64 tst-makedev tst-empty \
         tst-preadvwritev2 tst-preadvwritev64v2 tst-warn-wide \
         tst-ldbl-warn tst-ldbl-error tst-dbl-efgcvt tst-ldbl-efgcvt \
-        tst-mntent-autofs
+        tst-mntent-autofs tst-syscalls
 
 # Tests which need libdl.
 ifeq (yes,$(build-shared))
diff --git a/misc/tst-syscalls.c b/misc/tst-syscalls.c
new file mode 100644 (file)
index 0000000..cfcd382
--- /dev/null
@@ -0,0 +1,167 @@
+/* Test for syscall interfaces.
+   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/>.  */
+
+/* This test verifies that the x32 system call handling zero-extends
+   unsigned 32-bit arguments to the 64-bit argument registers for
+   system calls (bug 25810).  The bug is specific to x32, but the test
+   should pass on all architectures.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <support/check.h>
+#include <support/xunistd.h>
+
+/* On x32, this can be passed in a single 64-bit integer register.  */
+struct Array
+{
+  size_t length;
+  void *ptr;
+};
+
+static int error_count;
+
+__attribute__ ((noclone, noinline))
+struct Array
+allocate (size_t bytes)
+{
+  if (!bytes)
+    return __extension__ (struct Array) {0, 0};
+
+  void *p = mmap (0x0, bytes, PROT_READ | PROT_WRITE,
+                 MAP_PRIVATE | MAP_ANON, -1, 0);
+  if (p == MAP_FAILED)
+    return __extension__ (struct Array) {0, 0};
+
+  return __extension__ (struct Array) {bytes, p};
+}
+
+__attribute__ ((noclone, noinline))
+void
+deallocate (struct Array b)
+{
+  /* On x32, the 64-bit integer register containing `b' may be copied
+     to another 64-bit integer register to pass the second argument to
+     munmap.  */
+  if (b.length && munmap (b.ptr, b.length))
+    {
+      printf ("munmap error: %m\n");
+      error_count++;
+    }
+}
+
+__attribute__ ((noclone, noinline))
+void *
+do_mmap (void *addr, size_t length)
+{
+  return mmap (addr, length, PROT_READ | PROT_WRITE,
+              MAP_PRIVATE | MAP_ANON, -1, 0);
+}
+
+__attribute__ ((noclone, noinline))
+void *
+reallocate (struct Array b)
+{
+  /* On x32, the 64-bit integer register containing `b' may be copied
+     to another 64-bit integer register to pass the second argument to
+     do_mmap.  */
+  if (b.length)
+    return do_mmap (b.ptr, b.length);
+  return NULL;
+}
+
+__attribute__ ((noclone, noinline))
+void
+protect (struct Array b)
+{
+  if (b.length)
+    {
+      /* On x32, the 64-bit integer register containing `b' may be copied
+        to another 64-bit integer register to pass the second argument
+        to mprotect.  */
+      if (mprotect (b.ptr, b.length,
+                   PROT_READ | PROT_WRITE | PROT_EXEC))
+       {
+         printf ("mprotect error: %m\n");
+         error_count++;
+       }
+    }
+}
+
+__attribute__ ((noclone, noinline))
+ssize_t
+do_read (int fd, void *ptr, struct Array b)
+{
+  /* On x32, the 64-bit integer register containing `b' may be copied
+     to another 64-bit integer register to pass the second argument to
+     read.  */
+  if (b.length)
+    return read (fd, ptr, b.length);
+  return 0;
+}
+
+__attribute__ ((noclone, noinline))
+ssize_t
+do_write (int fd, void *ptr, struct Array b)
+{
+  /* On x32, the 64-bit integer register containing `b' may be copied
+     to another 64-bit integer register to pass the second argument to
+     write.  */
+  if (b.length)
+    return write (fd, ptr, b.length);
+  return 0;
+}
+
+static int
+do_test (void)
+{
+  struct Array array;
+
+  array = allocate (1);
+  protect (array);
+  deallocate (array);
+  void *p = reallocate (array);
+  if (p == MAP_FAILED)
+    {
+      printf ("mmap error: %m\n");
+      error_count++;
+    }
+  array.ptr = p;
+  protect (array);
+  deallocate (array);
+
+  int fd = xopen ("/dev/null", O_RDWR, 0);
+  char buf[2];
+  array.ptr = buf;
+  if (do_read (fd, array.ptr, array) == -1)
+    {
+      printf ("read error: %m\n");
+      error_count++;
+    }
+  if (do_write (fd, array.ptr, array) == -1)
+    {
+      printf ("write error: %m\n");
+      error_count++;
+    }
+  xclose (fd);
+
+  return error_count ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+#include <support/test-driver.c>
index 584e0ffd96e238769b358cdc0bbfc064115f51ce..2df4c9098c7383d29a4b594e56791c2c0e1ad086 100644 (file)
@@ -332,7 +332,7 @@ tests-internal := tst-rwlock19 tst-rwlock20 \
                  tst-mutexpi8 tst-mutexpi8-static tst-cancel25
 
 xtests = tst-setuid1 tst-setuid1-static tst-setuid2 \
-       tst-mutexpp1 tst-mutexpp6 tst-mutexpp10
+       tst-mutexpp1 tst-mutexpp6 tst-mutexpp10 tst-setgroups
 
 # This test can run into task limits because of a linux kernel bug
 # and then cause the make process to fail too, see bug 24537.
index 9dcf480bdfcce927a03337b08ee33d317bcc8d84..5f1f35e9a4a618d61282c4be8a8aca9a902cd020 100644 (file)
@@ -94,7 +94,13 @@ struct pthread_unwind_buf
 struct xid_command
 {
   int syscall_no;
-  long int id[3];
+  /* Enforce zero-extension for the pointer argument in
+
+     int setgroups (size_t size, const gid_t *list);
+
+     The kernel XID arguments are unsigned and do not require sign
+     extension.  */
+  unsigned long int id[3];
   volatile int cntr;
   volatile int error; /* -1: no call yet, 0: success seen, >0: error seen.  */
 };
diff --git a/nptl/tst-setgroups.c b/nptl/tst-setgroups.c
new file mode 100644 (file)
index 0000000..ae3c1b1
--- /dev/null
@@ -0,0 +1,79 @@
+/* Test setgroups as root and in the presence of threads (Bug 26248)
+   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 <stdlib.h>
+#include <limits.h>
+#include <grp.h>
+#include <errno.h>
+#include <error.h>
+#include <support/xthread.h>
+#include <support/support.h>
+#include <support/test-driver.h>
+#include <support/xunistd.h>
+
+/* The purpose of this test is to test the setgroups API as root and in
+   the presence of threads.  Once we create a thread the setgroups
+   implementation must ensure that all threads are set to the same
+   group and this operation should not fail. Lastly we test setgroups
+   with a zero sized group and a bad address and verify we get EPERM.  */
+
+static void *
+start_routine (void *args)
+{
+  return NULL;
+}
+
+static int
+do_test (void)
+{
+  int size;
+  /* NB: Stack address can be at 0xfffXXXXX on 32-bit OSes.  */
+  gid_t list[NGROUPS_MAX];
+  int status = EXIT_SUCCESS;
+
+  pthread_t thread = xpthread_create (NULL, start_routine, NULL);
+
+  size = getgroups (sizeof (list) / sizeof (list[0]), list);
+  if (size < 0)
+    {
+      status = EXIT_FAILURE;
+      error (0, errno, "getgroups failed");
+    }
+  if (setgroups (size, list) < 0)
+    {
+      if (errno == EPERM)
+       status = EXIT_UNSUPPORTED;
+      else
+       {
+         status = EXIT_FAILURE;
+         error (0, errno, "setgroups failed");
+       }
+    }
+
+  if (status == EXIT_SUCCESS && setgroups (0, list) < 0)
+    {
+      status = EXIT_FAILURE;
+      error (0, errno, "setgroups failed");
+    }
+
+  xpthread_join (thread);
+
+  return status;
+}
+
+#include <support/test-driver.c>
index a4ea8008e201b9397aa4274bb558de471b0573af..1ebf924826c60b6ec035346ed7b00bf6da1c0fc7 100644 (file)
@@ -33,6 +33,7 @@
 #ifdef HAVE_LIBAUDIT
 # include <libaudit.h>
 #endif
+#include <libc-diag.h>
 
 #include "dbg_log.h"
 #include "selinux.h"
@@ -320,6 +321,12 @@ avc_free_lock (void *lock)
 }
 
 
+/* avc_init (along with several other symbols) was marked as deprecated by the
+   SELinux API starting from version 3.1.  We use it here, but should
+   eventually switch to the newer API.  */
+DIAG_PUSH_NEEDS_COMMENT
+DIAG_IGNORE_NEEDS_COMMENT (10, "-Wdeprecated-declarations");
+
 /* Initialize the user space access vector cache (AVC) for NSCD along with
    log/thread/lock callbacks.  */
 void
@@ -335,7 +342,14 @@ nscd_avc_init (void)
   audit_init ();
 #endif
 }
+DIAG_POP_NEEDS_COMMENT
+
 
+/* security_context_t and sidput (along with several other symbols) were marked
+   as deprecated by the SELinux API starting from version 3.1.  We use them
+   here, but should eventually switch to the newer API.  */
+DIAG_PUSH_NEEDS_COMMENT
+DIAG_IGNORE_NEEDS_COMMENT (10, "-Wdeprecated-declarations");
 
 /* Check the permission from the caller (via getpeercon) to nscd.
    Returns 0 if access is allowed, 1 if denied, and -1 on error.
@@ -422,6 +436,7 @@ out:
 
   return rc;
 }
+DIAG_POP_NEEDS_COMMENT
 
 
 /* Wrapper to get AVC statistics.  */
index 8e389a1683747cf1047f4de8fe603f2b5ccc5f3f..8e1e8ec9adc9f66204c18127b6f070473a733e4d 100644 (file)
@@ -38,6 +38,7 @@
 #include <sys/stat.h>
 #include <sys/uio.h>
 #include "nss_db/nss_db.h"
+#include <libc-diag.h>
 
 /* Get libc version number.  */
 #include "../version.h"
@@ -841,6 +842,13 @@ print_database (int fd)
 
 
 #ifdef HAVE_SELINUX
+
+/* security_context_t and matchpathcon (along with several other symbols) were
+   marked as deprecated by the SELinux API starting from version 3.1.  We use
+   them here, but should eventually switch to the newer API.  */
+DIAG_PUSH_NEEDS_COMMENT
+DIAG_IGNORE_NEEDS_COMMENT (10, "-Wdeprecated-declarations");
+
 static void
 set_file_creation_context (const char *outname, mode_t mode)
 {
@@ -870,6 +878,7 @@ set_file_creation_context (const char *outname, mode_t mode)
       freecon (ctx);
     }
 }
+DIAG_POP_NEEDS_COMMENT
 
 static void
 reset_file_creation_context (void)
index a8de1e03b38dee47b9f28a486475923f9d42b799..f8b19a5cf0960a615a526db6798cfba79acc21f6 100644 (file)
@@ -142,7 +142,7 @@ _nss_compat_setgrent (int stayopen)
 }
 
 
-static enum nss_status
+static enum nss_status __attribute_warn_unused_result__
 internal_endgrent (ent_t *ent)
 {
   if (ent->stream != NULL)
@@ -163,6 +163,15 @@ internal_endgrent (ent_t *ent)
   return NSS_STATUS_SUCCESS;
 }
 
+/* Like internal_endgrent, but preserve errno in all cases.  */
+static void
+internal_endgrent_noerror (ent_t *ent)
+{
+  int saved_errno = errno;
+  enum nss_status unused __attribute__ ((unused)) = internal_endgrent (ent);
+  __set_errno (saved_errno);
+}
+
 enum nss_status
 _nss_compat_endgrent (void)
 {
@@ -483,7 +492,7 @@ _nss_compat_getgrnam_r (const char *name, struct group *grp,
   if (result == NSS_STATUS_SUCCESS)
     result = internal_getgrnam_r (name, grp, &ent, buffer, buflen, errnop);
 
-  internal_endgrent (&ent);
+  internal_endgrent_noerror (&ent);
 
   return result;
 }
@@ -612,7 +621,7 @@ _nss_compat_getgrgid_r (gid_t gid, struct group *grp,
   if (result == NSS_STATUS_SUCCESS)
     result = internal_getgrgid_r (gid, grp, &ent, buffer, buflen, errnop);
 
-  internal_endgrent (&ent);
+  internal_endgrent_noerror (&ent);
 
   return result;
 }
index 939b25b33be88345744b3f71ea3247a2e5f54612..7591442ff9caf9c6113b07b9ac777e6d3af37681 100644 (file)
@@ -133,7 +133,7 @@ internal_setgrent (ent_t *ent)
 }
 
 
-static enum nss_status
+static enum nss_status __attribute_warn_unused_result__
 internal_endgrent (ent_t *ent)
 {
   if (ent->stream != NULL)
@@ -157,6 +157,15 @@ internal_endgrent (ent_t *ent)
   return NSS_STATUS_SUCCESS;
 }
 
+/* Like internal_endgrent, but preserve errno in all cases.  */
+static void
+internal_endgrent_noerror (ent_t *ent)
+{
+  int saved_errno = errno;
+  enum nss_status unused __attribute__ ((unused)) = internal_endgrent (ent);
+  __set_errno (saved_errno);
+}
+
 /* Add new group record.  */
 static void
 add_group (long int *start, long int *size, gid_t **groupsp, long int limit,
@@ -501,7 +510,7 @@ _nss_compat_initgroups_dyn (const char *user, gid_t group, long int *start,
  done:
   scratch_buffer_free (&tmpbuf);
 
-  internal_endgrent (&intern);
+  internal_endgrent_noerror (&intern);
 
   return status;
 }
index ec3f35c594574afc774106f030ffb666884290c6..bd5e707da017e5e400669f80ab0d061b9f949c10 100644 (file)
@@ -259,7 +259,7 @@ _nss_compat_setpwent (int stayopen)
 }
 
 
-static enum nss_status
+static enum nss_status __attribute_warn_unused_result__
 internal_endpwent (ent_t *ent)
 {
   if (ent->stream != NULL)
@@ -287,6 +287,15 @@ internal_endpwent (ent_t *ent)
   return NSS_STATUS_SUCCESS;
 }
 
+/* Like internal_endpwent, but preserve errno in all cases.  */
+static void
+internal_endpwent_noerror (ent_t *ent)
+{
+  int saved_errno = errno;
+  enum nss_status unused __attribute__ ((unused)) = internal_endpwent (ent);
+  __set_errno (saved_errno);
+}
+
 enum nss_status
 _nss_compat_endpwent (void)
 {
@@ -822,7 +831,7 @@ _nss_compat_getpwnam_r (const char *name, struct passwd *pwd,
   if (result == NSS_STATUS_SUCCESS)
     result = internal_getpwnam_r (name, pwd, &ent, buffer, buflen, errnop);
 
-  internal_endpwent (&ent);
+  internal_endpwent_noerror (&ent);
 
   return result;
 }
@@ -1061,7 +1070,7 @@ _nss_compat_getpwuid_r (uid_t uid, struct passwd *pwd,
   if (result == NSS_STATUS_SUCCESS)
     result = internal_getpwuid_r (uid, pwd, &ent, buffer, buflen, errnop);
 
-  internal_endpwent (&ent);
+  internal_endpwent_noerror (&ent);
 
   return result;
 }
index f6b7a1ef1588a926109646168315aabec255e872..d0e3c51b454699a55074bb6a4972f046d591b8d6 100644 (file)
@@ -215,7 +215,7 @@ _nss_compat_setspent (int stayopen)
 }
 
 
-static enum nss_status
+static enum nss_status __attribute_warn_unused_result__
 internal_endspent (ent_t *ent)
 {
   if (ent->stream != NULL)
@@ -244,6 +244,15 @@ internal_endspent (ent_t *ent)
   return NSS_STATUS_SUCCESS;
 }
 
+/* Like internal_endspent, but preserve errno in all cases.  */
+static void
+internal_endspent_noerror (ent_t *ent)
+{
+  int saved_errno = errno;
+  enum nss_status unused __attribute__ ((unused)) = internal_endspent (ent);
+  __set_errno (saved_errno);
+}
+
 enum nss_status
 _nss_compat_endspent (void)
 {
@@ -261,7 +270,6 @@ _nss_compat_endspent (void)
   return result;
 }
 
-
 static enum nss_status
 getspent_next_nss_netgr (const char *name, struct spwd *result, ent_t *ent,
                         char *group, char *buffer, size_t buflen,
@@ -786,7 +794,7 @@ _nss_compat_getspnam_r (const char *name, struct spwd *pwd,
   if (result == NSS_STATUS_SUCCESS)
     result = internal_getspnam_r (name, pwd, &ent, buffer, buflen, errnop);
 
-  internal_endspent (&ent);
+  internal_endspent_noerror (&ent);
 
   return result;
 }
index cba9cd18198a010c44c4455bc5e877a4618895ad..4580cefb9fabc9f1b3186144a08d1ae870fc090a 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 45214b59e4ddb79b2982e76dfc8d227e6caba8db..4615f6dfe76444df3c060e3c3012983e8f7252dd 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 b6c5aea08f78dca54d5ac4731098aa3db490e24a..eddea33f4c8b700c7e52cb2269ef3d308e00d3d7 100644 (file)
    <https://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 509e0d69b1a08f8105bc332fa2eb904d6a593d7d..201536d24e09a8c62a4d527a7afdc5f46dad49ac 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 548130e413058d0ccd44646b1f7933327aeaac30..a8ff52c072e8241f526337d2acd843874dcccca4 100644 (file)
@@ -234,8 +234,13 @@ L(entry_no_page_cross):
 #endif
        /* calculate the loc value */
        cmeq    datav.16b, datav.16b, #0
+#ifdef __AARCH64EB__
+       mov     data1, datav.d[1]
+       mov     data2, datav.d[0]
+#else
        mov     data1, datav.d[0]
        mov     data2, datav.d[1]
+#endif
        cmp     data1, 0
        csel    data1, data1, data2, ne
        mov     pos, 8
index 5981247dd961e85a19a679d58b23f19da820ce89..086a5c7e994ccd1a3db5f7c73f15e0bf6e0e2d5d 100644 (file)
@@ -154,8 +154,13 @@ L(loop_end):
           byte.  */
 
        cmeq    datav.16b, datav.16b, #0
+#ifdef __AARCH64EB__
+       mov     data1, datav.d[1]
+       mov     data2, datav.d[0]
+#else
        mov     data1, datav.d[0]
        mov     data2, datav.d[1]
+#endif
        cmp     data1, 0
        csel    data1, data1, data2, ne
        sub     len, src, srcin
index bf4ac7077f3b700982abafd7f456bd7a90d12ca7..379bb56fc93bee78da220847bb5739e878ea3d3c 100644 (file)
@@ -268,7 +268,7 @@ ENTRY(memcpy)
 
        mov     dst, dstin      /* Preserve dstin, we need to return it.  */
        cmp     count, #64
-       bge     .Lcpy_not_short
+       bhs     .Lcpy_not_short
        /* Deal with small copies quickly by dropping straight into the
           exit block.  */
 
@@ -351,10 +351,10 @@ ENTRY(memcpy)
 
 1:
        subs    tmp2, count, #64        /* Use tmp2 for count.  */
-       blt     .Ltail63aligned
+       blo     .Ltail63aligned
 
        cmp     tmp2, #512
-       bge     .Lcpy_body_long
+       bhs     .Lcpy_body_long
 
 .Lcpy_body_medium:                     /* Count in tmp2.  */
 #ifdef USE_VFP
@@ -378,7 +378,7 @@ ENTRY(memcpy)
        add     src, src, #64
        vstr    d1, [dst, #56]
        add     dst, dst, #64
-       bge     1b
+       bhs     1b
        tst     tmp2, #0x3f
        beq     .Ldone
 
@@ -412,7 +412,7 @@ ENTRY(memcpy)
        ldrd    A_l, A_h, [src, #64]!
        strd    A_l, A_h, [dst, #64]!
        subs    tmp2, tmp2, #64
-       bge     1b
+       bhs     1b
        tst     tmp2, #0x3f
        bne     1f
        ldr     tmp2,[sp], #FRAME_SIZE
@@ -482,7 +482,7 @@ ENTRY(memcpy)
        add     src, src, #32
 
        subs    tmp2, tmp2, #prefetch_lines * 64 * 2
-       blt     2f
+       blo     2f
 1:
        cpy_line_vfp    d3, 0
        cpy_line_vfp    d4, 64
@@ -494,7 +494,7 @@ ENTRY(memcpy)
        add     dst, dst, #2 * 64
        add     src, src, #2 * 64
        subs    tmp2, tmp2, #prefetch_lines * 64
-       bge     1b
+       bhs     1b
 
 2:
        cpy_tail_vfp    d3, 0
@@ -615,8 +615,8 @@ ENTRY(memcpy)
 1:
        pld     [src, #(3 * 64)]
        subs    count, count, #64
-       ldrmi   tmp2, [sp], #FRAME_SIZE
-       bmi     .Ltail63unaligned
+       ldrlo   tmp2, [sp], #FRAME_SIZE
+       blo     .Ltail63unaligned
        pld     [src, #(4 * 64)]
 
 #ifdef USE_NEON
@@ -633,7 +633,7 @@ ENTRY(memcpy)
        neon_load_multi d0-d3, src
        neon_load_multi d4-d7, src
        subs    count, count, #64
-       bmi     2f
+       blo     2f
 1:
        pld     [src, #(4 * 64)]
        neon_store_multi d0-d3, dst
@@ -641,7 +641,7 @@ ENTRY(memcpy)
        neon_store_multi d4-d7, dst
        neon_load_multi d4-d7, src
        subs    count, count, #64
-       bpl     1b
+       bhs     1b
 2:
        neon_store_multi d0-d3, dst
        neon_store_multi d4-d7, dst
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 510e8adaf242c78222b46f7d92d08aeccd357076..bcfbc51d99b96b2a86caf211527c59915fe5d252 100644 (file)
@@ -68,7 +68,7 @@ ENTRY(memcpy)
                cfi_remember_state
 
                subs    r2, r2, #4
-               blt     8f
+               blo     8f
                ands    ip, r0, #3
        PLD(    pld     [r1, #0]                )
                bne     9f
@@ -82,7 +82,7 @@ ENTRY(memcpy)
                cfi_rel_offset (r6, 4)
                cfi_rel_offset (r7, 8)
                cfi_rel_offset (r8, 12)
-               blt     5f
+               blo     5f
 
        CALGN(  ands    ip, r1, #31             )
        CALGN(  rsb     r3, ip, #32             )
@@ -98,9 +98,9 @@ ENTRY(memcpy)
 #endif
 
        PLD(    pld     [r1, #0]                )
-2:     PLD(    subs    r2, r2, #96             )
+2:     PLD(    cmp     r2, #96                 )
        PLD(    pld     [r1, #28]               )
-       PLD(    blt     4f                      )
+       PLD(    blo     4f                      )
        PLD(    pld     [r1, #60]               )
        PLD(    pld     [r1, #92]               )
 
@@ -108,9 +108,7 @@ ENTRY(memcpy)
 4:             ldmia   r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
                subs    r2, r2, #32
                stmia   r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
-               bge     3b
-       PLD(    cmn     r2, #96                 )
-       PLD(    bge     4b                      )
+               bhs     3b
 
 5:             ands    ip, r2, #28
                rsb     ip, ip, #32
@@ -222,7 +220,7 @@ ENTRY(memcpy)
                strbge  r4, [r0], #1
                subs    r2, r2, ip
                strb    lr, [r0], #1
-               blt     8b
+               blo     8b
                ands    ip, r1, #3
                beq     1b
 
@@ -236,7 +234,7 @@ ENTRY(memcpy)
                .macro  forward_copy_shift pull push
 
                subs    r2, r2, #28
-               blt     14f
+               blo     14f
 
        CALGN(  ands    ip, r1, #31             )
        CALGN(  rsb     ip, ip, #32             )
@@ -253,9 +251,9 @@ ENTRY(memcpy)
                cfi_rel_offset (r10, 16)
 
        PLD(    pld     [r1, #0]                )
-       PLD(    subs    r2, r2, #96             )
+       PLD(    cmp     r2, #96                 )
        PLD(    pld     [r1, #28]               )
-       PLD(    blt     13f                     )
+       PLD(    blo     13f                     )
        PLD(    pld     [r1, #60]               )
        PLD(    pld     [r1, #92]               )
 
@@ -280,9 +278,7 @@ ENTRY(memcpy)
                mov     ip, ip, PULL #\pull
                orr     ip, ip, lr, PUSH #\push
                stmia   r0!, {r3, r4, r5, r6, r7, r8, r10, ip}
-               bge     12b
-       PLD(    cmn     r2, #96                 )
-       PLD(    bge     13b                     )
+               bhs     12b
 
                pop     {r5 - r8, r10}
                cfi_adjust_cfa_offset (-20)
index 954037ef3ad9c1018e1be2aab927ca8336136e04..0d07b76ee6d3db27c091675b909a10026bfad528 100644 (file)
@@ -85,7 +85,7 @@ ENTRY(memmove)
                add     r1, r1, r2
                add     r0, r0, r2
                subs    r2, r2, #4
-               blt     8f
+               blo     8f
                ands    ip, r0, #3
        PLD(    pld     [r1, #-4]               )
                bne     9f
@@ -99,7 +99,7 @@ ENTRY(memmove)
                cfi_rel_offset (r6, 4)
                cfi_rel_offset (r7, 8)
                cfi_rel_offset (r8, 12)
-               blt     5f
+               blo     5f
 
        CALGN(  ands    ip, r1, #31             )
        CALGN(  sbcsne  r4, ip, r2              )  @ C is always set here
@@ -114,9 +114,9 @@ ENTRY(memmove)
 #endif
 
        PLD(    pld     [r1, #-4]               )
-2:     PLD(    subs    r2, r2, #96             )
+2:     PLD(    cmp     r2, #96                 )
        PLD(    pld     [r1, #-32]              )
-       PLD(    blt     4f                      )
+       PLD(    blo     4f                      )
        PLD(    pld     [r1, #-64]              )
        PLD(    pld     [r1, #-96]              )
 
@@ -124,9 +124,7 @@ ENTRY(memmove)
 4:             ldmdb   r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
                subs    r2, r2, #32
                stmdb   r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
-               bge     3b
-       PLD(    cmn     r2, #96                 )
-       PLD(    bge     4b                      )
+               bhs     3b
 
 5:             ands    ip, r2, #28
                rsb     ip, ip, #32
@@ -237,7 +235,7 @@ ENTRY(memmove)
                strbge  r4, [r0, #-1]!
                subs    r2, r2, ip
                strb    lr, [r0, #-1]!
-               blt     8b
+               blo     8b
                ands    ip, r1, #3
                beq     1b
 
@@ -251,7 +249,7 @@ ENTRY(memmove)
                .macro  backward_copy_shift push pull
 
                subs    r2, r2, #28
-               blt     14f
+               blo     14f
 
        CALGN(  ands    ip, r1, #31             )
        CALGN(  rsb     ip, ip, #32             )
@@ -268,9 +266,9 @@ ENTRY(memmove)
                cfi_rel_offset (r10, 16)
 
        PLD(    pld     [r1, #-4]               )
-       PLD(    subs    r2, r2, #96             )
+       PLD(    cmp     r2, #96                 )
        PLD(    pld     [r1, #-32]              )
-       PLD(    blt     13f                     )
+       PLD(    blo     13f                     )
        PLD(    pld     [r1, #-64]              )
        PLD(    pld     [r1, #-96]              )
 
@@ -295,9 +293,7 @@ ENTRY(memmove)
                mov     r4, r4, PUSH #\push
                orr     r4, r4, r3, PULL #\pull
                stmdb   r0!, {r4 - r8, r10, ip, lr}
-               bge     12b
-       PLD(    cmn     r2, #96                 )
-       PLD(    bge     13b                     )
+               bhs     12b
 
                pop     {r5 - r8, r10}
                cfi_adjust_cfa_offset (-20)
diff --git a/sysdeps/generic/unwind-arch.h b/sysdeps/generic/unwind-arch.h
new file mode 100644 (file)
index 0000000..d712e5e
--- /dev/null
@@ -0,0 +1,30 @@
+/* Return backtrace of current program state.  Arch-specific bits.
+   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/>.  */
+
+#ifndef _UNWIND_ARCH_H
+#define _UNWIND_ARCH_H
+
+#include <unwind.h>
+
+static inline void *
+unwind_arch_adjustment (void *prev, void *addr)
+{
+  return addr;
+}
+
+#endif
index 0a373972840836a4c27d0383453514329d5bc8bb..25ca8f846317051b9c7988717cfed2c94b85b6dc 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 9e98366ea3b09612d54a3e956d5c35c1bdc86560..8ecff97706f12165778e33357372166fe32702cd 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 0114ca8b19467eaf3396363c4de0abfe52b2fecf..d0804b30c03bff6bdae45c463bf666e0993cd415 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 b4bcd8fb6c605130029bfed4fbf1ff02f48c7563..6094af8fec912c345afc225070cf17ffc0fe1975 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 995e90d6da1242c037a7dfe83a756071eeb7be7c..6030adf7e7e3dadea62bb1d973dd462e81d62f19 100644 (file)
@@ -17,5 +17,8 @@
 # <https://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 5f742321ae2f8dfeda8ea33d1ee7babc03759de8..bcdf20179fe53c3c7facb02b7f536a5d8fe8924d 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 e613e6a3447086ebc19b9d27acffd0049c639687..a03f478fc74672ee05d05405403b4075c498fadf 100644 (file)
@@ -101,7 +101,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
@@ -144,14 +145,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
@@ -186,6 +187,9 @@ do_system (const char *line)
     }
   DO_UNLOCK ();
 
+  if (ret != 0)
+    __set_errno (ret);
+
   return status;
 }
 
index 2ba009e919bee2499a1761c448aa197b89055a81..829eec266af1597c99240508a9a933df0033623c 100644 (file)
@@ -179,8 +179,8 @@ GOT_LABEL:                  ;                                             \
 #else
 /* Position-dependent code does not require access to the GOT.  */
 # define __GLRO(rOUT, rGOT, member, offset)                            \
-       lis     rOUT,(member+LOWORD)@ha;                                        \
-       lwz     rOUT,(member+LOWORD)@l(rOUT)
+       lis     rOUT,(member)@ha;                                       \
+       lwz     rOUT,(member)@l(rOUT)
 #endif /* PIC */
 
 #endif /* __ASSEMBLER__ */
index c07626677f06d615bd03fdb4ba2a0c4e9591698d..4f6c3490a20bc3eb34f11f1e7aab0ddec7e82e5d 100644 (file)
@@ -30,6 +30,7 @@
 # P: optionally-NULL pointer to typed object (e.g., 3rd argument to sigaction)
 # s: non-NULL string (e.g., 1st arg to open)
 # S: optionally-NULL string (e.g., 1st arg to acct)
+# U: unsigned long int (32-bit types are zero-extended to 64-bit types)
 # v: vararg scalar (e.g., optional 3rd arg to open)
 # V: byte-per-page vector (3rd arg to mincore)
 # W: wait status, optionally-NULL pointer to int (e.g., 2nd arg of wait4)
@@ -184,6 +185,27 @@ while read file srcfile caller syscall args strong weak; do
   ?:?????????) nargs=9;;
   esac
 
+  # Derive the unsigned long int arguments from the argument signature
+  ulong_arg_1=0
+  ulong_arg_2=0
+  ulong_count=0
+  for U in $(echo $args | sed -e "s/.*:/:/" | grep -ob U)
+  do
+    ulong_count=$(expr $ulong_count + 1)
+    ulong_arg=$(echo $U | sed -e "s/:U//")
+    case $ulong_count in
+    1)
+      ulong_arg_1=$ulong_arg
+      ;;
+    2)
+      ulong_arg_2=$ulong_arg
+      ;;
+    *)
+      echo >&2 "$0: Too many unsigned long int arguments for syscall ($strong $weak)"
+      exit 2
+    esac
+  done
+
   # Make sure only the first syscall rule is used, if multiple dirs
   # define the same syscall.
   echo ''
@@ -245,6 +267,8 @@ while read file srcfile caller syscall args strong weak; do
        \$(make-target-directory)
        (echo '#define SYSCALL_NAME $syscall'; \\
         echo '#define SYSCALL_NARGS $nargs'; \\
+        echo '#define SYSCALL_ULONG_ARG_1 $ulong_arg_1'; \\
+        echo '#define SYSCALL_ULONG_ARG_2 $ulong_arg_2'; \\
         echo '#define SYSCALL_SYMBOL $strong'; \\
         echo '#define SYSCALL_NOERRNO $noerrno'; \\
         echo '#define SYSCALL_ERRVAL $errval'; \\
index cf6c7a58fbf094b7ef6027b16136fcc756a6e20e..f807a8603f623b783d93379313e1da06e2e7b119 100644 (file)
    defining a few macros:
        SYSCALL_NAME            syscall name
        SYSCALL_NARGS           number of arguments this call takes
+       SYSCALL_ULONG_ARG_1     the first unsigned long int argument this
+                               call takes.  0 means that there are no
+                               unsigned long int arguments.
+       SYSCALL_ULONG_ARG_2     the second unsigned long int argument this
+                               call takes.  0 means that there is at most
+                               one unsigned long int argument.
        SYSCALL_SYMBOL          primary symbol name
        SYSCALL_NOERRNO         1 to define a no-errno version (see below)
        SYSCALL_ERRVAL          1 to define an error-value version (see below)
 /* This indirection is needed so that SYMBOL gets macro-expanded.  */
 #define syscall_hidden_def(SYMBOL)             hidden_def (SYMBOL)
 
-#define T_PSEUDO(SYMBOL, NAME, N)              PSEUDO (SYMBOL, NAME, N)
-#define T_PSEUDO_NOERRNO(SYMBOL, NAME, N)      PSEUDO_NOERRNO (SYMBOL, NAME, N)
-#define T_PSEUDO_ERRVAL(SYMBOL, NAME, N)       PSEUDO_ERRVAL (SYMBOL, NAME, N)
+/* If PSEUDOS_HAVE_ULONG_INDICES is defined, PSEUDO and T_PSEUDO macros
+   have 2 extra arguments for unsigned long int arguments:
+     Extra argument 1: Position of the first unsigned long int argument.
+     Extra argument 2: Position of the second unsigned long int argument.
+ */
+#ifndef PSEUDOS_HAVE_ULONG_INDICES
+# undef SYSCALL_ULONG_ARG_1
+# define SYSCALL_ULONG_ARG_1 0
+#endif
+
+#if SYSCALL_ULONG_ARG_1
+# define T_PSEUDO(SYMBOL, NAME, N, U1, U2) \
+  PSEUDO (SYMBOL, NAME, N, U1, U2)
+# define T_PSEUDO_NOERRNO(SYMBOL, NAME, N, U1, U2) \
+  PSEUDO_NOERRNO (SYMBOL, NAME, N, U1, U2)
+# define T_PSEUDO_ERRVAL(SYMBOL, NAME, N, U1, U2) \
+  PSEUDO_ERRVAL (SYMBOL, NAME, N, U1, U2)
+#else
+# define T_PSEUDO(SYMBOL, NAME, N) \
+  PSEUDO (SYMBOL, NAME, N)
+# define T_PSEUDO_NOERRNO(SYMBOL, NAME, N) \
+  PSEUDO_NOERRNO (SYMBOL, NAME, N)
+# define T_PSEUDO_ERRVAL(SYMBOL, NAME, N) \
+  PSEUDO_ERRVAL (SYMBOL, NAME, N)
+#endif
 #define T_PSEUDO_END(SYMBOL)                   PSEUDO_END (SYMBOL)
 #define T_PSEUDO_END_NOERRNO(SYMBOL)           PSEUDO_END_NOERRNO (SYMBOL)
 #define T_PSEUDO_END_ERRVAL(SYMBOL)            PSEUDO_END_ERRVAL (SYMBOL)
 /* This kind of system call stub never returns an error.
    We return the return value register to the caller unexamined.  */
 
+# if SYSCALL_ULONG_ARG_1
+T_PSEUDO_NOERRNO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS,
+                 SYSCALL_ULONG_ARG_1, SYSCALL_ULONG_ARG_2)
+# else
 T_PSEUDO_NOERRNO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
+# endif
        ret_NOERRNO
 T_PSEUDO_END_NOERRNO (SYSCALL_SYMBOL)
 
@@ -66,7 +99,12 @@ T_PSEUDO_END_NOERRNO (SYSCALL_SYMBOL)
    value, or zero for success.  We may massage the kernel's return value
    to meet that ABI, but we never set errno here.  */
 
+# if SYSCALL_ULONG_ARG_1
+T_PSEUDO_ERRVAL (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS,
+                SYSCALL_ULONG_ARG_1, SYSCALL_ULONG_ARG_2)
+# else
 T_PSEUDO_ERRVAL (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
+# endif
        ret_ERRVAL
 T_PSEUDO_END_ERRVAL (SYSCALL_SYMBOL)
 
@@ -75,7 +113,12 @@ T_PSEUDO_END_ERRVAL (SYSCALL_SYMBOL)
 /* This is a "normal" system call stub: if there is an error,
    it returns -1 and sets errno.  */
 
+# if SYSCALL_ULONG_ARG_1
+T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS,
+         SYSCALL_ULONG_ARG_1, SYSCALL_ULONG_ARG_2)
+# else
 T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
+# endif
        ret
 T_PSEUDO_END (SYSCALL_SYMBOL)
 
index e28e801c7acf6dbf43781abfa87b9d46a241cfce..6b22b2cb45888fd6f5b4c7a497a9181050b9ecc4 100644 (file)
@@ -39,27 +39,27 @@ kill                -       kill            i:ii    __kill          kill
 link           -       link            i:ss    __link          link
 listen         -       listen          i:ii    __listen        listen
 lseek          -       lseek           i:iii   __libc_lseek    __lseek lseek
-madvise                -       madvise         i:pii   __madvise       madvise
+madvise                -       madvise         i:pUi   __madvise       madvise
 mkdir          -       mkdir           i:si    __mkdir         mkdir
-mmap           -       mmap            b:aniiii __mmap         mmap
-mprotect       -       mprotect        i:aii   __mprotect      mprotect
-munmap         -       munmap          i:ai    __munmap        munmap
+mmap           -       mmap            b:aUiiii __mmap         mmap
+mprotect       -       mprotect        i:aUi   __mprotect      mprotect
+munmap         -       munmap          i:aU    __munmap        munmap
 open           -       open            Ci:siv  __libc_open __open open
 profil         -       profil          i:piii  __profil        profil
 ptrace         -       ptrace          i:iiii  ptrace
-read           -       read            Ci:ibn  __libc_read     __read read
-readlink       -       readlink        i:spi   __readlink      readlink
+read           -       read            Ci:ibU  __libc_read     __read read
+readlink       -       readlink        i:spU   __readlink      readlink
 readv          -       readv           Ci:ipi  __readv         readv
 reboot         -       reboot          i:i     reboot
-recv           -       recv            Ci:ibni __libc_recv     recv
-recvfrom       -       recvfrom        Ci:ibniBN       __libc_recvfrom __recvfrom recvfrom
+recv           -       recv            Ci:ibUi __libc_recv     recv
+recvfrom       -       recvfrom        Ci:ibUiBN       __libc_recvfrom __recvfrom recvfrom
 recvmsg                -       recvmsg         Ci:ipi  __libc_recvmsg  __recvmsg recvmsg
 rename         -       rename          i:ss    rename
 rmdir          -       rmdir           i:s     __rmdir         rmdir
 select         -       select          Ci:iPPPP        __select        __libc_select select
-send           -       send            Ci:ibni __libc_send     __send send
+send           -       send            Ci:ibUi __libc_send     __send send
 sendmsg                -       sendmsg         Ci:ipi  __libc_sendmsg  __sendmsg sendmsg
-sendto         -       sendto          Ci:ibnibn       __libc_sendto   __sendto sendto
+sendto         -       sendto          Ci:ibUibn       __libc_sendto   __sendto sendto
 setdomain      -       setdomainname   i:si    setdomainname
 setegid                -       setegid         i:i     __setegid       setegid
 seteuid                -       seteuid         i:i     __seteuid       seteuid
@@ -94,5 +94,5 @@ uname         -       uname           i:p     __uname         uname
 unlink         -       unlink          i:s     __unlink        unlink
 utimes         -       utimes          i:sp    __utimes        utimes
 vhangup                -       vhangup         i:i     vhangup
-write          -       write           Ci:ibn  __libc_write    __write write
+write          -       write           Ci:ibU  __libc_write    __write write
 writev         -       writev          Ci:ipi  __writev        writev
index f12b7b1a2d0aced49dad0c18be4024b065fa6e9b..5fbde369c397b7bb37c33519eec0f3c45a51ca74 100644 (file)
@@ -60,7 +60,9 @@ sysdep_routines += adjtimex clone umount umount2 readahead \
                   setfsuid setfsgid epoll_pwait signalfd \
                   eventfd eventfd_read eventfd_write prlimit \
                   personality epoll_wait tee vmsplice splice \
-                  open_by_handle_at mlock2 pkey_mprotect pkey_set pkey_get
+                  open_by_handle_at mlock2 pkey_mprotect pkey_set pkey_get \
+                  prctl \
+                  process_vm_readv process_vm_writev
 
 CFLAGS-gethostid.c = -fexceptions
 CFLAGS-tee.c = -fexceptions -fasynchronous-unwind-tables
index 9378387747de250eab53e731d24e4559e1dd6db4..c8471947b9c209be6add1e528f892f1a6c54f966 100644 (file)
@@ -17,6 +17,7 @@
 #define __NR_clock_nanosleep 115
 #define __NR_clock_settime 112
 #define __NR_clone 220
+#define __NR_clone3 435
 #define __NR_close 57
 #define __NR_connect 203
 #define __NR_copy_file_range 285
index a60053b914451ddb01802cd3f56d355ecc8fe044..08af68b5e840b5d89afbaa22e5192cf371b17c6a 100644 (file)
@@ -7,6 +7,9 @@ libc.so: malloc
 libc.so: memalign
 libc.so: realloc
 libm.so: matherr
+# If outline atomics are used, libgcc (built outside of glibc) may
+# call __getauxval using the PLT.
+libc.so: __getauxval ?
 # The dynamic loader needs __tls_get_addr for TLS.
 ld.so: __tls_get_addr
 # The main malloc is interposed into the dynamic linker, for
index 9d8ffbe8603647ab6fb12636cf69a4a055275f5a..bf61b66b70532998c379750ac409835e3d241e0f 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 ed873d9dd42274087a80e5749a13d746b2443fba..796663a23a04a3dff4e2c86d3968f28538ba91d8 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 b2bbf10181391a7bfcb16b5bf5ea724848839c85..ff445a54060c91ae7d1bfddff47e76bd7f931c1a 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 572d7c1137fa53fcacbb73bbfcccd7756dd16b66..2b4a3117d194a64731de3c95349d2faaa486fe6d 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 05164cb253713c4a3ae408911976e6bd7f51526b..2723bbb138a3198c92cd012993fc752934be66e0 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 9bf551ace8ba89bdb59bbe91191c8474ff8f25e3..f23ede025931dd6c415905d4667e28e6aa99b493 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 92f16e27243fd7f66dd81592089e43a0caf020f3..43c05f8050bd77c31681374fbfde1fd51cf702e5 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 fa985a96e526051590a604191533164c3ac9ee4e..16a567e83463d155f183e099856d99236909008e 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 f042ac815dbab55a3094d6c971bc4ef249a2d12d..c0a856c344d64779899f62304a6a2ec63747ec64 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 dfe2f7feb5b901e0e94f9d81be02d4978cc5ccbb..042768ebf2b44231400e801f7fb6dee6e22af22b 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 39de510357cbad619f5b4c5fd13e5c0fe3ca605f..8658d822ab62dac2e933b2898432e769f2ddddf6 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 beefcf284b885d5310fb85d1a1f9887663a0fc20..0c6a83e9b3ef6e7f8a45530f914db186397ee817 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)
 
 union __mips_syscall_return
   {
-    long long val;
+    long long int val;
     struct
       {
-       long v0;
-       long v1;
+       long int v0;
+       long int v1;
       }
     reg;
   };
@@ -152,13 +152,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                                                         \
@@ -175,14 +175,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                                                         \
@@ -199,15 +200,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                                                         \
@@ -225,16 +228,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                                                         \
@@ -252,16 +258,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                                                         \
@@ -285,63 +295,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;                                                 \
 })
index f96636538a80861a235452315e89c2e6b37a00a3..4a9d7054f9e474c65408dac977a367233674db32 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                                                         \
index 9d30291f8465f0c6dd988c773e076a9ad94a75d2..3e1f1cc3c598f6a005f0dd4cadd05f6214c4196b 100644 (file)
@@ -50,7 +50,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                                                         \
index 26adf2cd041b3d3545805cb24e57968cd428b0fd..a9baff3c1716b83a12a0e932f185360e976fe7dc 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 cdfc0b1b5871699d5a0194fd125eda6af3c992bf..a4cf1540fe4bc9f525796b3e55acfdf164ed1dcf 100644 (file)
@@ -36,8 +36,8 @@
    the INTERNAL_SYSCALL_{ERROR_P,ERRNO} macros work correctly.  */
 #define INTERNAL_VSYSCALL_CALL(funcptr, err, nr, args...)              \
   ({                                                                   \
-    long _ret = funcptr (args);                                                \
-    err = ((unsigned long) (_ret) >= (unsigned long) -4095L);          \
+    long int _ret = funcptr (args);                                    \
+    err = ((unsigned long int) (_ret) >= (unsigned long int) -4095L);  \
     if (err)                                                           \
       _ret = -_ret;                                                    \
     _ret;                                                              \
diff --git a/sysdeps/unix/sysv/linux/mips/unwind-arch.h b/sysdeps/unix/sysv/linux/mips/unwind-arch.h
new file mode 100644 (file)
index 0000000..a009899
--- /dev/null
@@ -0,0 +1,67 @@
+/* Return backtrace of current program state.  Arch-specific bits.
+   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/>.  */
+
+#ifndef _UNWIND_ARCH_H
+#define _UNWIND_ARCH_H
+
+#include <stdint.h>
+
+/* MIPS fallback code handle a frame where its FDE can not be obtained
+   (for instance a signal frame) by reading the kernel allocated signal frame
+   and adding '2' to the value of 'sc_pc' [1].  The added value is used to
+   recognize an end of an EH region on mips16 [2].
+
+   The idea here is to adjust the obtained signal frame ADDR value and remove
+   the libgcc added value by checking if the previous frame is a signal frame
+   one.
+
+   [1] libgcc/config/mips/linux-unwind.h from gcc code.
+   [2] gcc/config/mips/mips.h from gcc code.  */
+
+static inline void *
+unwind_arch_adjustment (void *prev, void *addr)
+{
+  uint32_t *pc = (uint32_t *) prev;
+
+  if (pc == NULL)
+    return addr;
+
+  /* For MIPS16 or microMIPS frame libgcc makes no adjustment.  */
+  if ((uintptr_t) pc & 0x3)
+    return addr;
+
+  /* The vDSO containes either
+
+     24021061 li v0, 0x1061 (rt_sigreturn)
+     0000000c syscall
+       or
+     24021017 li v0, 0x1017 (sigreturn)
+     0000000c syscall  */
+  if (pc[1] != 0x0000000c)
+    return addr;
+#if _MIPS_SIM == _ABIO32
+  if (pc[0] == (0x24020000 | __NR_sigreturn))
+    return (void *) ((uintptr_t) addr - 2);
+#endif
+  if (pc[0] == (0x24020000 | __NR_rt_sigreturn))
+    return (void *) ((uintptr_t) addr - 2);
+
+  return addr;
+}
+
+#endif
index 27879e76cd79dc2b3139acca2c0913eefb9d0305..fd46aec1a0172a342833c10667a1121a575a2a68 100644 (file)
@@ -21,6 +21,7 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <errno.h>
+#include <linux/posix_types.h>  /* For __kernel_mode_t.  */
 
 #ifndef DEFAULT_VERSION
 # ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T
@@ -61,7 +62,6 @@ __new_msgctl (int msqid, int cmd, struct msqid_ds *buf)
 
   int ret = msgctl_syscall (msqid, cmd, buf);
 
-#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
   if (ret >= 0)
     {
       switch (cmd)
@@ -69,10 +69,16 @@ __new_msgctl (int msqid, int cmd, struct msqid_ds *buf)
        case IPC_STAT:
        case MSG_STAT:
        case MSG_STAT_ANY:
+#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
          buf->msg_perm.mode >>= 16;
+#else
+         /* Old Linux kernel versions might not clear the mode padding.  */
+         if (sizeof ((struct msqid_ds){0}.msg_perm.mode)
+             != sizeof (__kernel_mode_t))
+           buf->msg_perm.mode &= 0xFFFF;
+#endif
        }
     }
-#endif
 
   return ret;
 }
diff --git a/sysdeps/unix/sysv/linux/nios2/kernel-features.h b/sysdeps/unix/sysv/linux/nios2/kernel-features.h
deleted file mode 100644 (file)
index d68d114..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Set flags signalling availability of kernel features based on given
-   kernel version number.  NIOS2 version.
-   Copyright (C) 2019-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_next <kernel-features.h>
-
-#undef __ASSUME_SYSVIPC_DEFAULT_IPC_64
index 725dfafde8670818d871c24b6b366fea902af781..ffc150851e778079016d6d27258132ac56b2399c 100644 (file)
 # define LOADARGS_0(name, dummy)                                             \
        r0 = name
 # define LOADARGS_1(name, __arg1) \
-       long int arg1 = (long int) (__arg1);    \
+       long int _arg1 = (long int) (__arg1);   \
   LOADARGS_0(name, 0);                                    \
        extern void __illegally_sized_syscall_arg1 (void); \
        if (__builtin_classify_type (__arg1) != 5 && sizeof (__arg1) > 4) \
          __illegally_sized_syscall_arg1 (); \
-       r3 = arg1
+       r3 = _arg1
 # define LOADARGS_2(name, __arg1, __arg2) \
-       long int arg2 = (long int) (__arg2); \
+       long int _arg2 = (long int) (__arg2); \
        LOADARGS_1(name, __arg1); \
        extern void __illegally_sized_syscall_arg2 (void); \
        if (__builtin_classify_type (__arg2) != 5 && sizeof (__arg2) > 4) \
          __illegally_sized_syscall_arg2 (); \
-       r4 = arg2
+       r4 = _arg2
 # define LOADARGS_3(name, __arg1, __arg2, __arg3) \
-       long int arg3 = (long int) (__arg3); \
+       long int _arg3 = (long int) (__arg3); \
        LOADARGS_2(name, __arg1, __arg2); \
        extern void __illegally_sized_syscall_arg3 (void); \
        if (__builtin_classify_type (__arg3) != 5 && sizeof (__arg3) > 4) \
          __illegally_sized_syscall_arg3 (); \
-       r5 = arg3
+       r5 = _arg3
 # define LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4) \
-       long int arg4 = (long int) (__arg4); \
+       long int _arg4 = (long int) (__arg4); \
        LOADARGS_3(name, __arg1, __arg2, __arg3); \
        extern void __illegally_sized_syscall_arg4 (void); \
        if (__builtin_classify_type (__arg4) != 5 && sizeof (__arg4) > 4) \
          __illegally_sized_syscall_arg4 (); \
-       r6 = arg4
+       r6 = _arg4
 # define LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5) \
-       long int arg5 = (long int) (__arg5); \
+       long int _arg5 = (long int) (__arg5); \
        LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4); \
        extern void __illegally_sized_syscall_arg5 (void); \
        if (__builtin_classify_type (__arg5) != 5 && sizeof (__arg5) > 4) \
          __illegally_sized_syscall_arg5 (); \
-       r7 = arg5
+       r7 = _arg5
 # define LOADARGS_6(name, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) \
-       long int arg6 = (long int) (__arg6); \
+       long int _arg6 = (long int) (__arg6); \
        LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5); \
        extern void __illegally_sized_syscall_arg6 (void); \
        if (__builtin_classify_type (__arg6) != 5 && sizeof (__arg6) > 4) \
          __illegally_sized_syscall_arg6 (); \
-       r8 = arg6
+       r8 = _arg6
 
 # define ASM_INPUT_0 "0" (r0)
 # define ASM_INPUT_1 ASM_INPUT_0, "1" (r3)
index ee7f43653d9aa0e17c3334154d7622ef397ceb3d..8a3f1c43e4320620c794c602f65f6ed9f26aba8a 100644 (file)
 #define LOADARGS_0(name, dummy) \
        r0 = name
 #define LOADARGS_1(name, __arg1) \
-       long int arg1 = (long int) (__arg1); \
+       long int _arg1 = (long int) (__arg1); \
        LOADARGS_0(name, 0); \
        extern void __illegally_sized_syscall_arg1 (void); \
        if (__builtin_classify_type (__arg1) != 5 && sizeof (__arg1) > 8) \
          __illegally_sized_syscall_arg1 (); \
-       r3 = arg1
+       r3 = _arg1
 #define LOADARGS_2(name, __arg1, __arg2) \
-       long int arg2 = (long int) (__arg2); \
+       long int _arg2 = (long int) (__arg2); \
        LOADARGS_1(name, __arg1); \
        extern void __illegally_sized_syscall_arg2 (void); \
        if (__builtin_classify_type (__arg2) != 5 && sizeof (__arg2) > 8) \
          __illegally_sized_syscall_arg2 (); \
-       r4 = arg2
+       r4 = _arg2
 #define LOADARGS_3(name, __arg1, __arg2, __arg3) \
-       long int arg3 = (long int) (__arg3); \
+       long int _arg3 = (long int) (__arg3); \
        LOADARGS_2(name, __arg1, __arg2); \
        extern void __illegally_sized_syscall_arg3 (void); \
        if (__builtin_classify_type (__arg3) != 5 && sizeof (__arg3) > 8) \
          __illegally_sized_syscall_arg3 (); \
-       r5 = arg3
+       r5 = _arg3
 #define LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4) \
-       long int arg4 = (long int) (__arg4); \
+       long int _arg4 = (long int) (__arg4); \
        LOADARGS_3(name, __arg1, __arg2, __arg3); \
        extern void __illegally_sized_syscall_arg4 (void); \
        if (__builtin_classify_type (__arg4) != 5 && sizeof (__arg4) > 8) \
          __illegally_sized_syscall_arg4 (); \
-       r6 = arg4
+       r6 = _arg4
 #define LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5) \
-       long int arg5 = (long int) (__arg5); \
+       long int _arg5 = (long int) (__arg5); \
        LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4); \
        extern void __illegally_sized_syscall_arg5 (void); \
        if (__builtin_classify_type (__arg5) != 5 && sizeof (__arg5) > 8) \
          __illegally_sized_syscall_arg5 (); \
-       r7 = arg5
+       r7 = _arg5
 #define LOADARGS_6(name, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) \
-       long int arg6 = (long int) (__arg6); \
+       long int _arg6 = (long int) (__arg6); \
        LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5); \
        extern void __illegally_sized_syscall_arg6 (void); \
        if (__builtin_classify_type (__arg6) != 5 && sizeof (__arg6) > 8) \
          __illegally_sized_syscall_arg6 (); \
-       r8 = arg6
+       r8 = _arg6
 
 #define ASM_INPUT_0 "0" (r0)
 #define ASM_INPUT_1 ASM_INPUT_0, "1" (r3)
diff --git a/sysdeps/unix/sysv/linux/prctl.c b/sysdeps/unix/sysv/linux/prctl.c
new file mode 100644 (file)
index 0000000..d5725f1
--- /dev/null
@@ -0,0 +1,42 @@
+/* prctl - Linux specific syscall.
+   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>
+#include <stdarg.h>
+#include <sys/prctl.h>
+
+/* Unconditionally read all potential arguments.  This may pass
+   garbage values to the kernel, but avoids the need for teaching
+   glibc the argument counts of individual options (including ones
+   that are added to the kernel in the future).  */
+
+int
+__prctl (int option, ...)
+{
+  va_list arg;
+  va_start (arg, option);
+  unsigned long int arg2 = va_arg (arg, unsigned long int);
+  unsigned long int arg3 = va_arg (arg, unsigned long int);
+  unsigned long int arg4 = va_arg (arg, unsigned long int);
+  unsigned long int arg5 = va_arg (arg, unsigned long int);
+  va_end (arg);
+  return INLINE_SYSCALL_CALL (prctl, option, arg2, arg3, arg4, arg5);
+}
+
+libc_hidden_def (__prctl)
+weak_alias (__prctl, prctl)
diff --git a/sysdeps/unix/sysv/linux/process_vm_readv.c b/sysdeps/unix/sysv/linux/process_vm_readv.c
new file mode 100644 (file)
index 0000000..e1377f7
--- /dev/null
@@ -0,0 +1,32 @@
+/* process_vm_readv - Linux specific syscall.
+   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 <unistd.h>
+#include <sysdep.h>
+#include <errno.h>
+#include <sys/uio.h>
+
+ssize_t
+process_vm_readv (pid_t pid, const struct iovec *local_iov,
+                 unsigned long int liovcnt,
+                 const struct iovec *remote_iov,
+                 unsigned long int riovcnt, unsigned long int flags)
+{
+  return INLINE_SYSCALL_CALL (process_vm_readv, pid, local_iov,
+                             liovcnt, remote_iov, riovcnt, flags);
+}
diff --git a/sysdeps/unix/sysv/linux/process_vm_writev.c b/sysdeps/unix/sysv/linux/process_vm_writev.c
new file mode 100644 (file)
index 0000000..944ab9b
--- /dev/null
@@ -0,0 +1,32 @@
+/* process_vm_writev - Linux specific syscall.
+   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 <unistd.h>
+#include <sysdep.h>
+#include <errno.h>
+#include <sys/uio.h>
+
+ssize_t
+process_vm_writev (pid_t pid, const struct iovec *local_iov,
+                  unsigned long int liovcnt,
+                  const struct iovec *remote_iov,
+                  unsigned long int riovcnt, unsigned long int flags)
+{
+  return INLINE_SYSCALL_CALL (process_vm_writev, pid, local_iov,
+                             liovcnt, remote_iov, riovcnt, flags);
+}
index 201bf9a91b967575fe45f8c2eac41d3dd297f1e0..2bd9b16f32199f5444f90589ed48e32ed871ff44 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 0c3eb0932f04f23206ab98babb725b987bcdb1fa..30571af49ff91bfe18b70049ff930295ec10aef3 100644 (file)
@@ -22,6 +22,7 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <errno.h>
+#include <linux/posix_types.h>  /* For __kernel_mode_t.  */
 
 /* Define a `union semun' suitable for Linux here.  */
 union semun
@@ -92,7 +93,6 @@ __new_semctl (int semid, int semnum, int cmd, ...)
 
   int ret = semctl_syscall (semid, semnum, cmd, arg);
 
-#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
   if (ret >= 0)
     {
       switch (cmd)
@@ -100,10 +100,16 @@ __new_semctl (int semid, int semnum, int cmd, ...)
         case IPC_STAT:
         case SEM_STAT:
         case SEM_STAT_ANY:
+#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
           arg.buf->sem_perm.mode >>= 16;
+#else
+         /* Old Linux kernel versions might not clear the mode padding.  */
+         if (sizeof ((struct semid_ds){0}.sem_perm.mode)
+             != sizeof (__kernel_mode_t))
+           arg.buf->sem_perm.mode &= 0xFFFF;
+#endif
        }
     }
-#endif
 
   return ret;
 }
index 39fa861e17a1c9d3b50f8b6fd7bb32c8742ed8a4..f41b359b8b0323256b3a4f662d5fe28cf7c8beab 100644 (file)
@@ -22,6 +22,7 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <errno.h>
+#include <linux/posix_types.h>  /* For __kernel_mode_t.  */
 
 #ifndef DEFAULT_VERSION
 # ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T
@@ -63,7 +64,6 @@ __new_shmctl (int shmid, int cmd, struct shmid_ds *buf)
 
   int ret = shmctl_syscall (shmid, cmd, buf);
 
-#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
   if (ret >= 0)
     {
       switch (cmd)
@@ -71,10 +71,16 @@ __new_shmctl (int shmid, int cmd, struct shmid_ds *buf)
         case IPC_STAT:
         case SHM_STAT:
         case SHM_STAT_ANY:
+#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
           buf->shm_perm.mode >>= 16;
+#else
+         /* Old Linux kernel versions might not clear the mode padding.  */
+         if (sizeof ((struct shmid_ds){0}.shm_perm.mode)
+             != sizeof (__kernel_mode_t))
+           buf->shm_perm.mode &= 0xFFFF;
+#endif
        }
     }
-#endif
 
   return ret;
 }
index b0d182a439ed6dc051603a8768107f265c33569e..1475039677c3f2f6fefe61d1c6d137d6df66d7cd 100644 (file)
@@ -11,8 +11,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 6b2f664226142f76b4443ee1daeddf0b4594e1bc..938aa7aa8c92fc5be9b77862a87d0f29d9fd6c67 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 9c0dc2a630121c03dc7c00403d7808b1ad40becf..4e26172321006a983daa99714adc246bd8f19fcf 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 36e087d8f437534210c35c494784b5c7d57c604e..3d89814003a2225773c1291361fb200bb37f607c 100644 (file)
@@ -21,8 +21,8 @@
 # This file can list all potential system calls.  The names are only
 # used if the installed kernel headers also provide them.
 
-# The list of system calls is current as of Linux 5.4.
-kernel 5.4
+# The list of system calls is current as of Linux 5.5.
+kernel 5.5
 
 FAST_atomic_update
 FAST_cmpxchg
index 5f1352ad434536dd604fe3e0067326e3bf5fe6de..52e6dafc86fd151409a7ef12e4ebb2cc7b7f4d67 100644 (file)
@@ -28,25 +28,24 @@ inotify_add_watch   EXTRA   inotify_add_watch       i:isi   inotify_add_watch
 inotify_init   EXTRA   inotify_init    i:      inotify_init
 inotify_init1  EXTRA   inotify_init1   i:I     inotify_init1
 inotify_rm_watch       EXTRA   inotify_rm_watch        i:ii    inotify_rm_watch
-ioperm         -       ioperm          i:iii   ioperm
+ioperm         -       ioperm          i:UUi   ioperm
 iopl           -       iopl            i:i     iopl
 klogctl                EXTRA   syslog          i:isi   klogctl
 lchown         -       lchown          i:sii   __lchown        lchown
-mincore                -       mincore         i:anV   mincore
-mlock          -       mlock           i:bn    mlock
+mincore                -       mincore         i:aUV   mincore
+mlock          -       mlock           i:bU    mlock
 mlockall       -       mlockall        i:i     mlockall
-mount          EXTRA   mount           i:sssip __mount mount
-mremap         EXTRA   mremap          b:ainip __mremap        mremap
-munlock                -       munlock         i:ai    munlock
+mount          EXTRA   mount           i:sssUp __mount mount
+mremap         EXTRA   mremap          b:aUUip __mremap        mremap
+munlock                -       munlock         i:aU    munlock
 munlockall     -       munlockall      i:      munlockall
 nfsservctl     EXTRA   nfsservctl      i:ipp   __compat_nfsservctl     nfsservctl@GLIBC_2.0:GLIBC_2.28
 pipe           -       pipe            i:f     __pipe          pipe
 pipe2          -       pipe2           i:fi    __pipe2         pipe2
 pivot_root     EXTRA   pivot_root      i:ss    pivot_root
-prctl          EXTRA   prctl           i:iiiii __prctl         prctl
 query_module   EXTRA   query_module    i:sipip __compat_query_module   query_module@GLIBC_2.0:GLIBC_2.23
 quotactl       EXTRA   quotactl        i:isip  quotactl
-remap_file_pages -     remap_file_pages i:piiii        __remap_file_pages remap_file_pages
+remap_file_pages -     remap_file_pages i:pUiUi        __remap_file_pages remap_file_pages
 sched_getp     -       sched_getparam  i:ip    __sched_getparam        sched_getparam
 sched_gets     -       sched_getscheduler      i:i     __sched_getscheduler    sched_getscheduler
 sched_primax   -       sched_get_priority_max  i:i     __sched_get_priority_max        sched_get_priority_max
@@ -55,8 +54,8 @@ sched_rr_gi   -       sched_rr_get_interval   i:ip    __sched_rr_get_interval sched_rr_get_in
 sched_setp     -       sched_setparam  i:ip    __sched_setparam        sched_setparam
 sched_sets     -       sched_setscheduler      i:iip   __sched_setscheduler    sched_setscheduler
 sched_yield    -       sched_yield     i:      __sched_yield   sched_yield
-sendfile       -       sendfile        i:iipi  sendfile
-sendfile64     -       sendfile64      i:iipi  sendfile64
+sendfile       -       sendfile        i:iipU  sendfile
+sendfile64     -       sendfile64      i:iipU  sendfile64
 setfsgid       EXTRA   setfsgid        i:i     setfsgid
 setfsuid       EXTRA   setfsuid        i:i     setfsuid
 setpgid                -       setpgid         i:ii    __setpgid       setpgid
@@ -73,19 +72,19 @@ chown               -       chown           i:sii   __libc_chown    __chown chown
 fchownat       -       fchownat        i:isiii fchownat
 linkat         -       linkat          i:isisi linkat
 mkdirat                -       mkdirat         i:isi   mkdirat
-readlinkat     -       readlinkat      i:issi  readlinkat
+readlinkat     -       readlinkat      i:issU  readlinkat
 symlinkat      -       symlinkat       i:sis   symlinkat
 unlinkat       -       unlinkat        i:isi   unlinkat
 
-setxattr       -       setxattr        i:sspii setxattr
-lsetxattr      -       lsetxattr       i:sspii lsetxattr
-fsetxattr      -       fsetxattr       i:ispii fsetxattr
-getxattr       -       getxattr        i:sspi  getxattr
-lgetxattr      -       lgetxattr       i:sspi  lgetxattr
-fgetxattr      -       fgetxattr       i:ispi  fgetxattr
-listxattr      -       listxattr       i:ssi   listxattr
-llistxattr     -       llistxattr      i:ssi   llistxattr
-flistxattr     -       flistxattr      i:isi   flistxattr
+setxattr       -       setxattr        i:sspUi setxattr
+lsetxattr      -       lsetxattr       i:sspUi lsetxattr
+fsetxattr      -       fsetxattr       i:ispUi fsetxattr
+getxattr       -       getxattr        i:sspU  getxattr
+lgetxattr      -       lgetxattr       i:sspU  lgetxattr
+fgetxattr      -       fgetxattr       i:ispU  fgetxattr
+listxattr      -       listxattr       i:ssU   listxattr
+llistxattr     -       llistxattr      i:ssU   llistxattr
+flistxattr     -       flistxattr      i:isU   flistxattr
 removexattr    -       removexattr     i:ss    removexattr
 lremovexattr   -       lremovexattr    i:ss    lremovexattr
 fremovexattr   -       fremovexattr    i:is    fremovexattr
@@ -102,8 +101,6 @@ name_to_handle_at EXTRA     name_to_handle_at i:isppi name_to_handle_at
 
 setns          EXTRA   setns           i:ii    setns
 
-process_vm_readv EXTRA process_vm_readv i:ipipii process_vm_readv
-process_vm_writev EXTRA        process_vm_writev i:ipipii process_vm_writev
 memfd_create    EXTRA  memfd_create    i:si    memfd_create
 pkey_alloc     EXTRA   pkey_alloc      i:ii    pkey_alloc
 pkey_free      EXTRA   pkey_free       i:i     pkey_free
index c2eb37e5753bc14359d05262db23307df18987fc..c7f740a1df36e034191fdfa3a9ec8ad1346fad93 100644 (file)
 #  define SYSCALL_ERROR_LABEL syscall_error
 # endif
 
+/* PSEUDO and T_PSEUDO macros have 2 extra arguments for unsigned long
+   int arguments.  */
+# define PSEUDOS_HAVE_ULONG_INDICES 1
+
+# ifndef SYSCALL_ULONG_ARG_1
+#  define SYSCALL_ULONG_ARG_1 0
+#  define SYSCALL_ULONG_ARG_2 0
+# endif
+
 # undef        PSEUDO
-# define PSEUDO(name, syscall_name, args)                                    \
-  .text;                                                                     \
-  ENTRY (name)                                                               \
-    DO_CALL (syscall_name, args);                                            \
-    cmpq $-4095, %rax;                                                       \
+# if SYSCALL_ULONG_ARG_1
+#  define PSEUDO(name, syscall_name, args, ulong_arg_1, ulong_arg_2) \
+  .text;                                                             \
+  ENTRY (name)                                                       \
+    DO_CALL (syscall_name, args, ulong_arg_1, ulong_arg_2);          \
+    cmpq $-4095, %rax;                                               \
     jae SYSCALL_ERROR_LABEL
+# else
+#  define PSEUDO(name, syscall_name, args) \
+  .text;                                                             \
+  ENTRY (name)                                                       \
+    DO_CALL (syscall_name, args, 0, 0);                                      \
+    cmpq $-4095, %rax;                                               \
+    jae SYSCALL_ERROR_LABEL
+# endif
 
 # undef        PSEUDO_END
 # define PSEUDO_END(name)                                                    \
   END (name)
 
 # undef        PSEUDO_NOERRNO
-# define PSEUDO_NOERRNO(name, syscall_name, args) \
-  .text;                                                                     \
-  ENTRY (name)                                                               \
-    DO_CALL (syscall_name, args)
+# if SYSCALL_ULONG_ARG_1
+#  define PSEUDO_NOERRNO(name, syscall_name, args, ulong_arg_1, ulong_arg_2) \
+  .text;                                                             \
+  ENTRY (name)                                                       \
+    DO_CALL (syscall_name, args, ulong_arg_1, ulong_arg_2)
+# else
+#  define PSEUDO_NOERRNO(name, syscall_name, args) \
+  .text;                                                             \
+  ENTRY (name)                                                       \
+    DO_CALL (syscall_name, args, 0, 0)
+# endif
 
 # undef        PSEUDO_END_NOERRNO
 # define PSEUDO_END_NOERRNO(name) \
 # define ret_NOERRNO ret
 
 # undef        PSEUDO_ERRVAL
-# define PSEUDO_ERRVAL(name, syscall_name, args) \
-  .text;                                                                     \
-  ENTRY (name)                                                               \
-    DO_CALL (syscall_name, args);                                            \
+# if SYSCALL_ULONG_ARG_1
+#  define PSEUDO_ERRVAL(name, syscall_name, args, ulong_arg_1, ulong_arg_2) \
+  .text;                                                       \
+  ENTRY (name)                                                 \
+    DO_CALL (syscall_name, args, ulong_arg_1, ulong_arg_2);    \
+    negq %rax
+# else
+#  define PSEUDO_ERRVAL(name, syscall_name, args) \
+  .text;                                                       \
+  ENTRY (name)                                                 \
+    DO_CALL (syscall_name, args, 0, 0);                                \
     negq %rax
+# endif
 
 # undef        PSEUDO_END_ERRVAL
 # define PSEUDO_END_ERRVAL(name) \
     Syscalls of more than 6 arguments are not supported.  */
 
 # undef        DO_CALL
-# define DO_CALL(syscall_name, args)           \
+# define DO_CALL(syscall_name, args, ulong_arg_1, ulong_arg_2) \
     DOARGS_##args                              \
+    ZERO_EXTEND_##ulong_arg_1                  \
+    ZERO_EXTEND_##ulong_arg_2                  \
     movl $SYS_ify (syscall_name), %eax;                \
     syscall;
 
 # define DOARGS_5 DOARGS_4
 # define DOARGS_6 DOARGS_5
 
+# define ZERO_EXTEND_0 /* nothing */
+# define ZERO_EXTEND_1 /* nothing */
+# define ZERO_EXTEND_2 /* nothing */
+# define ZERO_EXTEND_3 /* nothing */
+# define ZERO_EXTEND_4 /* nothing */
+# define ZERO_EXTEND_5 /* nothing */
+# define ZERO_EXTEND_6 /* nothing */
+
 #else  /* !__ASSEMBLER__ */
 /* Define a macro which expands inline into the wrapper code for a system
    call.  */
 /* Registers clobbered by syscall.  */
 # define REGISTERS_CLOBBERED_BY_SYSCALL "cc", "r11", "cx"
 
-/* Create a variable 'name' based on type 'X' to avoid explicit types.
-   This is mainly used set use 64-bits arguments in x32.   */
-#define TYPEFY(X, name) __typeof__ ((X) - (X)) name
-/* Explicit cast the argument to avoid integer from pointer warning on
-   x32.  */
-#define ARGIFY(X) ((__typeof__ ((X) - (X))) (X))
+/* NB: This also works when X is an array.  For an array X,  type of
+   (X) - (X) is ptrdiff_t, which is signed, since size of ptrdiff_t
+   == size of pointer, cast is a NOP.   */
+#define TYPEFY1(X) __typeof__ ((X) - (X))
+/* Explicit cast the argument.  */
+#define ARGIFY(X) ((TYPEFY1 (X)) (X))
+/* Create a variable 'name' based on type of variable 'X' to avoid
+   explicit types.  */
+#define TYPEFY(X, name) __typeof__ (ARGIFY (X)) name
 
 #undef INTERNAL_SYSCALL
 #define INTERNAL_SYSCALL(name, err, nr, args...)                       \
index 5bf9eed80b1110ef865b8a16503ea75ad488749a..62e6f8fe11fa31a10009d7c2bf0281f657dd35ab 100644 (file)
 #undef LO_HI_LONG
 #define LO_HI_LONG(val) (val)
 
+#ifdef __ASSEMBLER__
+/* Zero-extend 32-bit unsigned long int arguments to 64 bits.  */
+# undef ZERO_EXTEND_1
+# define ZERO_EXTEND_1 movl %edi, %edi;
+# undef ZERO_EXTEND_2
+# define ZERO_EXTEND_2 movl %esi, %esi;
+# undef ZERO_EXTEND_3
+# define ZERO_EXTEND_3 movl %edx, %edx;
+# if SYSCALL_ULONG_ARG_1 == 4 || SYSCALL_ULONG_ARG_2 == 4
+#  undef DOARGS_4
+#  define DOARGS_4 movl %ecx, %r10d;
+# else
+#  undef ZERO_EXTEND_4
+#  define ZERO_EXTEND_4 movl %r10d, %r10d;
+# endif
+# undef ZERO_EXTEND_5
+# define ZERO_EXTEND_5 movl %r8d, %r8d;
+# undef ZERO_EXTEND_6
+# define ZERO_EXTEND_6 movl %r9d, %r9d;
+#else /* !__ASSEMBLER__ */
+# undef ARGIFY
+/* Enforce zero-extension for pointers and array system call arguments.
+   For integer types, extend to int64_t (the full register) using a
+   regular cast, resulting in zero or sign extension based on the
+   signedness of the original type.  */
+# define ARGIFY(X) \
+ ({                                                                    \
+    _Pragma ("GCC diagnostic push");                                   \
+    _Pragma ("GCC diagnostic ignored \"-Wpointer-to-int-cast\"");      \
+    (__builtin_classify_type (X) == 5                                  \
+     ? (uintptr_t) (X) : (int64_t) (X));                               \
+    _Pragma ("GCC diagnostic pop");                                    \
+  })
+#endif /* __ASSEMBLER__ */
+
 #endif /* linux/x86_64/x32/sysdep.h */
index c763b7d871f0e58a476a5dc85cf09ccc452e5d03..74953245aa238ec403b937bb58813cae32803154 100644 (file)
@@ -244,7 +244,7 @@ L(return):
        ret
 
 L(movsb):
-       cmpq    __x86_shared_non_temporal_threshold(%rip), %rdx
+       cmp     __x86_shared_non_temporal_threshold(%rip), %RDX_LP
        jae     L(more_8x_vec)
        cmpq    %rsi, %rdi
        jb      1f
@@ -402,7 +402,7 @@ L(more_8x_vec):
        addq    %r8, %rdx
 #if (defined USE_MULTIARCH || VEC_SIZE == 16) && IS_IN (libc)
        /* Check non-temporal store threshold.  */
-       cmpq    __x86_shared_non_temporal_threshold(%rip), %rdx
+       cmp     __x86_shared_non_temporal_threshold(%rip), %RDX_LP
        ja      L(large_forward)
 #endif
 L(loop_4x_vec_forward):
@@ -454,7 +454,7 @@ L(more_8x_vec_backward):
        subq    %r8, %rdx
 #if (defined USE_MULTIARCH || VEC_SIZE == 16) && IS_IN (libc)
        /* Check non-temporal store threshold.  */
-       cmpq    __x86_shared_non_temporal_threshold(%rip), %rdx
+       cmp     __x86_shared_non_temporal_threshold(%rip), %RDX_LP
        ja      L(large_backward)
 #endif
 L(loop_4x_vec_backward):
index 48d03a9f4616301df009f38f50939550f19d5b4c..ee82fa3e1970917d6872bc65e5be8fd511737005 100644 (file)
@@ -591,7 +591,14 @@ L(loop_cross_page_2_vec):
        movl    $(PAGE_SIZE / (VEC_SIZE * 4) - 1), %esi
 
        testq   %rdi, %rdi
+# ifdef USE_AS_STRNCMP
+       /* At this point, if %rdi value is 0, it already tested
+          VEC_SIZE*4+%r10 byte starting from %rax. This label
+          checks whether strncmp maximum offset reached or not.  */
+       je      L(string_nbyte_offset_check)
+# else
        je      L(back_to_loop)
+# endif
        tzcntq  %rdi, %rcx
        addq    %r10, %rcx
        /* Adjust for number of bytes skipped.  */
@@ -627,6 +634,14 @@ L(loop_cross_page_2_vec):
        VZEROUPPER
        ret
 
+# ifdef USE_AS_STRNCMP
+L(string_nbyte_offset_check):
+       leaq    (VEC_SIZE * 4)(%r10), %r10
+       cmpq    %r10, %r11
+       jbe     L(zero)
+       jmp     L(back_to_loop)
+# endif
+
        .p2align 4
 L(cross_page_loop):
        /* Check one byte/dword at a time.  */