Compare commits

...
Author SHA1 Message Date
Yvan Roux 59c0f6ff86 Suppress GCC 6 warning about ambiguous 'else' with -Wparentheses
Backport of df1cf48777.

	* stdlib/setenv.c (unsetenv): Fix ambiguous 'else'.
	* nis/nis_call.c (nis_server_cache_add): Likewise.
2016-05-09 10:03:50 -03:00
Stefan Liebler 94dc51ad84 S390: Fix "backtrace() returns infinitely deep stack frames with makecontext()" [BZ #18508].
On s390/s390x backtrace(buffer, size) returns the series of called functions until
"makecontext_ret" and additional entries (up to "size") with "makecontext_ret".
GDB-backtrace is also warning:
"Backtrace stopped: previous frame identical to this frame (corrupt stack?)"

To reproduce this scenario you have to setup a new context with makecontext()
and activate it with setcontext(). See e.g. cf() function in testcase stdlib/tst-makecontext.c.
Or see bug in libgo "Bug 66303 - runtime.Caller() returns infinitely deep stack frames
on s390x " (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66303).

This patch omits the cfi_startproc/cfi_endproc directives in ENTRY/END macro of
__makecontext_ret. Thus no frame information is generated in .eh_frame and backtrace
stops after __makecontext_ret. There is also no .eh_frame info for _start or
thread_start functions.

ChangeLog:

	[BZ #18508]
	* stdlib/Makefile ($(objpfx)tst-makecontext3):
	Depend on $(libdl).
	* stdlib/tst-makecontext.c (cf): Test if _Unwind_Backtrace
	is not called infinitely times.
	(backtrace_helper): New function.
	(trace_arg): New struct.
	(st1): Enlarge stack size.
	* sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S:
	(__makecontext_ret): Omit cfi_startproc and cfi_endproc.
	* sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S:
	Likewise.

(cherry picked from commit 890b7a4b33)
2016-04-28 10:30:09 +02:00
Stefan Liebler 50d2d4bb0e S/390: Fix setcontext/swapcontext which are not restoring sigmask.
This patch uses sigprocmask(SIG_SETMASK) instead of SIG_BLOCK
in setcontext, swapcontext.

(cherry picked from commit 2e807f2959)
2016-04-28 10:29:07 +02:00
Mike Frysinger 3a6219d3ec configure: fix test == usage
POSIX defines the = operator, but not ==.  Fix the few places where we
incorrectly used ==.

(cherry picked from commit b2d4456b33)
2016-04-09 20:10:33 -04:00
Stefan Liebler f5eb5f9c91 S390: Extend structs La_s390_regs / La_s390_retval with vector-registers.
Starting with z13, vector registers can also occur as argument registers.
Thus the passed input/output register structs for
la_s390_[32|64]_gnu_plt[enter|exit] functions should reflect those new
registers. This patch extends these structs La_s390_regs and La_s390_retval
and adjusts _dl_runtime_profile() to handle those fields in case of
running on a z13 machine.

ChangeLog:

	* sysdeps/s390/bits/link.h: (La_s390_vr) New typedef.
	(La_s390_32_regs): Append vector register lr_v24-lr_v31.
	(La_s390_64_regs): Likewise.
	(La_s390_32_retval): Append vector register lrv_v24.
	(La_s390_64_retval): Likeweise.
	* sysdeps/s390/s390-32/dl-trampoline.h (_dl_runtime_profile):
	Handle extended structs La_s390_32_regs and La_s390_32_retval.
	* sysdeps/s390/s390-64/dl-trampoline.h (_dl_runtime_profile):
	Handle extended structs La_s390_64_regs and La_s390_64_retval.

(cherry picked from commit 5cdd1989d1)
2016-04-04 13:19:57 +02:00
Stefan Liebler 3b7f56026c S390: Save and restore fprs/vrs while resolving symbols.
On s390, no fpr/vrs were saved while resolving a symbol
via _dl_runtime_resolve/_dl_runtime_profile.

According to the abi, the fpr-arguments are defined as call clobbered.
In leaf-functions, gcc 4.9 and newer can use fprs for saving/restoring gprs
instead of saving them to the stack.
If gcc do this in one of the resolver-functions, then the floating point
arguments of a library-function are invalid for the first library-function-call.
Thus, this patch saves/restores the fprs around the resolving code.

The same could occur for vector registers. Furthermore an ifunc-resolver
could also clobber the vector/floating point argument registers.
Thus this patch provides the further variants _dl_runtime_resolve_vx/
_dl_runtime_profile_vx, which are used if the kernel claims, that
we run on a machine with vector registers.

Furthermore, if _dl_runtime_profile calls _dl_call_pltexit,
the pointers to inregs-/outregs-structs were setup invalid.
Now they point to the correct location in the stack-frame.
Before branching back to the caller, the return values are now
restored instead of containing the return values of the
_dl_call_pltexit() call.
On s390-32, an endless loop occurs if _dl_call_pltexit() should be called.
Now, this code-path branches to this function instead of just after the
preceding basr-instruction.

ChangeLog:

	* sysdeps/s390/s390-32/dl-trampoline.S: Include dl-trampoline.h twice
	to create a non-vector/vector version for _dl_runtime_resolve and
	_dl_runtime_profile. Move implementation to ...
	* sysdeps/s390/s390-32/dl-trampoline.h: ... here.
	(_dl_runtime_resolve) Save and restore fpr/vrs.
	(_dl_runtime_profile) Save and restore vrs and fix some issues
	if _dl_call_pltexit is called.
	* sysdeps/s390/s390-32/dl-machine.h (elf_machine_runtime_setup):
	Choose the correct resolver function if running on a machine with vx.
	* sysdeps/s390/s390-64/dl-trampoline.S: Include dl-trampoline.h twice
	to create a non-vector/vector version for _dl_runtime_resolve and
	_dl_runtime_profile. Move implementation to ...
	* sysdeps/s390/s390-64/dl-trampoline.h: ... here.
	(_dl_runtime_resolve) Save and restore fpr/vrs.
	(_dl_runtime_profile) Save and restore vrs and fix some issues
	* sysdeps/s390/s390-64/dl-machine.h: (elf_machine_runtime_setup):
	Choose the correct resolver function if running on a machine with vx.

(cherry picked from commit 4603c51ef7
and commit d8a012c5c9)
2016-04-04 13:19:57 +02:00
Stefan Liebler daf161ce63 S390: configure check for vector instruction support in assembler.
The S390 specific test checks if the assembler has support for the new z13
vector instructions by compiling a vector instruction. The .machine and
.machinemode directives are needed to compile the vector instruction without
-march=z13 option on 31/64 bit.
On success the macro HAVE_S390_VX_ASM_SUPPORT is defined. This macro is used
to determine if the optimized functions can be build without compile errors.
If the used assembler lacks vector support, then a warning is dumped while
configuring and only the common code functions are build.

The z13 instruction support was introduced in
"[Committed] S/390: Add support for IBM z13."
(https://sourceware.org/ml/binutils/2015-01/msg00197.html)

ChangeLog:

	* config.h.in (HAVE_S390_VX_ASM_SUPPORT): New macro undefine.
	* sysdeps/s390/configure.ac: Add test for S390 vector instruction
	assembler support.
	* sysdeps/s390/configure: Regenerated.

(cherry picked from commit 4f0a1cea34)
2016-04-04 13:19:57 +02:00
Stefan Liebler 87efefb037 S390: Add new s390 platform.
The new IBM z13 is added to platform string array.
The macro _DL_PLATFORMS_COUNT is incremented to 8,
because it was not incremented by commit
"S/390: Sync AUXV capabilities and archs with kernel".

ChangeLog:

	* sysdeps/s390/dl-procinfo.c (_dl_s390_cap_flags): Add z13.
	* sysdeps/s390/dl-procinfo.h (_DL_PLATFORMS_COUNT): Increased.

(cherry picked from commit a1b0488fc9)
2016-04-04 13:19:57 +02:00
Stefan Liebler 65c7020d26 S390: Add hwcaps value for vector facility.
The HWCAP_S390_VX flag in hwcap field of auxiliary vector indicates
if the vector facility is available and the kernel is aware of it.
This can be tested with LD_SHOW_AUXV=1 <prog>.
Currently it does not show te, because it was not incremented
by commit "S/390: Add hwcap value for transactional execution.".
Thus _DL_HWCAP_COUNT is incremented by two.

ChangeLog:

	* sysdeps/s390/dl-procinfo.c (_dl_s390_platforms): Add vector flag.
	* sysdeps/s390/dl-procinfo.h: Add vector capability.
	* sysdeps/unix/sysv/linux/s390/bits/hwcap.h (HWCAP_S390_VX): Define.

(cherry picked from commit 4e28fa8088)
2016-04-04 13:19:57 +02:00
Hongjiu Zhang 9f95ec0adb sln: use stat64
When using sln on some filesystems which return 64-bit inodes,
the stat call might fail during install like so:
	.../elf/sln .../elf/symlink.list
	/lib32/libc.so.6: invalid destination: Value too large for defined data type
	/lib32/ld-linux.so.2: invalid destination: Value too large for defined data type
	Makefile:104: recipe for target 'install-symbolic-link' failed

Switch to using stat64 all the time to avoid this.

URL: https://bugs.gentoo.org/576396
(cherry picked from commit f5e753c8c3)
2016-03-07 11:45:43 -05:00
Stefan Liebler 1885fe873e S390: Do not use direct socket syscalls if build on kernels >= 4.3. [BZ #19682]
Beginning with Linux 4.3, the kernel headers contain direct
system call numbers __NR_socket etc. on s390x. On older kernels,
the socket-multiplexer syscall __NR_socketcall was used.

To enable these new syscalls, the patch
"S390: Call direct system calls for socket operations."
(https://sourceware.org/git/?p=glibc.git;a=commit;h=016495b818cb61df7d0d10e6db54074271b3e3a5)
was applied upstream.

If glibc 2.23 is configured with --enable-kernel=4.3 and newer,
the direct socket syscalls are used.
For older kernels, the socket-multiplexer syscall is used instead.

In glibc 2.22 and earlier, this patch is not applied.
If you build glibc on a kernel < 4.3, the socket-multiplexer
syscall is used. But if you build glibc on kernel >= 4.3, the
direct socket-syscalls are used. If you install this glibc on a
kernel < 4.3, all socket operations will fail.
See "Bug 19682 - s390x: Incorrect syscall definitions cause
breakage with Linux 4.3 headers"
(https://sourceware.org/bugzilla/show_bug.cgi?id=19682)
The configure switch --enable-kernel does not influence this
behaviour on older glibc-releases.

The solution is to remove the direct socket-syscalls in
sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list
(this patch) on older glibc-releases as it was done by the
upstream patch, too. These entries were never used on s390x,
but the c-files in sysdeps/unix/sysv/linux/.
After this removal, the behaviour of the socket functions are
not changed compared to the original glibc release version
and the socket-multiplexer-syscall is always used.
2016-03-03 08:22:43 +01:00
Carlos O'Donell 16d0a0ce76 CVE-2015-7547: getaddrinfo() stack-based buffer overflow (Bug 18665).
* A stack-based buffer overflow was found in libresolv when invoked from
  libnss_dns, allowing specially crafted DNS responses to seize control
  of execution flow in the DNS client.  The buffer overflow occurs in
  the functions send_dg (send datagram) and send_vc (send TCP) for the
  NSS module libnss_dns.so.2 when calling getaddrinfo with AF_UNSPEC
  family.  The use of AF_UNSPEC triggers the low-level resolver code to
  send out two parallel queries for A and AAAA.  A mismanagement of the
  buffers used for those queries could result in the response of a query
  writing beyond the alloca allocated buffer created by
  _nss_dns_gethostbyname4_r.  Buffer management is simplified to remove
  the overflow.  Thanks to the Google Security Team and Red Hat for
  reporting the security impact of this issue, and Robert Holiday of
  Ciena for reporting the related bug 18665. (CVE-2015-7547)

See also:
https://sourceware.org/ml/libc-alpha/2016-02/msg00416.html
https://sourceware.org/ml/libc-alpha/2016-02/msg00418.html

(cherry picked from commit e9db92d3ac)
2016-02-16 22:28:58 -05:00
Florian Weimer 014eaa2207 hsearch_r: Apply VM size limit in test case
(cherry picked from commit f34f146e68)
2016-02-16 21:52:07 +01:00
Florian Weimer 965630aefa Improve check against integer wraparound in hcreate_r [BZ #18240]
(cherry picked from commit bae7c7c764)
2016-01-29 18:01:51 +01:00
Ondřej Bílka 51e762570e Handle overflow in __hcreate_r
Hi,

As in bugzilla entry there is overflow in hsearch when looking for prime
number as SIZE_MAX - 1 is divisible by 5. We fix that by rejecting large
inputs before looking for prime.

	* misc/hsearch_r.c (__hcreate_r): Handle overflow.

(cherry picked from commit 2f5c175055)
2016-01-29 17:57:31 +01:00
Paul Pluzhnikov 163437ec37 Fix BZ #18985 -- out of range data to strftime() causes a segfault
(cherry picked from commit d36c75fc0d)
2016-01-23 18:16:50 +01:00
Paul Pluzhnikov f676ce661c Fix trailing space.
(cherry picked from commit 7565d2a862)
2016-01-23 18:14:45 +01:00
Paul Pluzhnikov 907cc11c57 Fix BZ #17905
(cherry picked from commit 0f58539030)
2016-01-23 18:14:15 +01:00
Szabolcs Nagy dbcaca73cb [AArch64] Fix the big endian loader name.
(cherry picked from commit 44cb254f9a)
2015-12-01 13:37:51 -02:00
Mike Frysinger 26f36461f6 nscd: drop selinux/flask.h include
Building nscd w/selinux enabled yields a warning which yields an error:
In file included from selinux.c:32:0:
/usr/include/selinux/flask.h:5:2: error:
 #warning "Please remove any #include's of this header in your source code."

I've done just that and it builds cleanly with libselinux-2.4.

(cherry picked from commit 8086966968)
2015-11-22 19:31:14 +01:00
Andreas Schwab e04da210f7 Fix parallel build error
(cherry picked from commit e8b6be0016)
2015-10-28 14:29:27 +00:00
Florian Weimer e871e19b5f CVE-2014-8121: Do not close NSS files database during iteration [BZ #18007]
Robin Hack discovered Samba would enter an infinite loop processing
certain quota-related requests.  We eventually tracked this down to a
glibc issue.

Running a (simplified) test case under strace shows that /etc/passwd
is continuously opened and closed:

…
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
lseek(3, 0, SEEK_CUR)                   = 0
read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 2717
lseek(3, 2717, SEEK_SET)                = 2717
close(3)                                = 0
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
lseek(3, 0, SEEK_CUR)                   = 0
lseek(3, 0, SEEK_SET)                   = 0
read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 2717
lseek(3, 2717, SEEK_SET)                = 2717
close(3)                                = 0
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
lseek(3, 0, SEEK_CUR)                   = 0
…

The lookup function implementation in
nss/nss_files/files-XXX.c:DB_LOOKUP has code to prevent that.  It is
supposed skip closing the input file if it was already open.

  /* Reset file pointer to beginning or open file.  */			      \
  status = internal_setent (keep_stream);				      \
									      \
  if (status == NSS_STATUS_SUCCESS)					      \
    {									      \
      /* Tell getent function that we have repositioned the file pointer.  */ \
      last_use = getby;							      \
									      \
      while ((status = internal_getent (result, buffer, buflen, errnop	      \
					H_ERRNO_ARG EXTRA_ARGS_VALUE))	      \
	     == NSS_STATUS_SUCCESS)					      \
	{ break_if_match }						      \
									      \
      if (! keep_stream)						      \
	internal_endent ();						      \
    }									      \

keep_stream is initialized from the stayopen flag in internal_setent.
internal_setent is called from the set*ent implementation as:

  status = internal_setent (stayopen);

However, for non-host database, this flag is always 0, per the
STAYOPEN magic in nss/getXXent_r.c.

Thus, the fix is this:

-  status = internal_setent (stayopen);
+  status = internal_setent (1);

This is not a behavioral change even for the hosts database (where the
application can specify the stayopen flag) because with a call to
sethostent(0), the file handle is still not closed in the
implementation of gethostent.

(cherry picked from commit 03d2730b44)

Conflicts:
	ChangeLog
	NEWS
2015-10-19 11:02:27 +02:00
Mike Frysinger f2cdbadd8a getmntent: fix memory corruption w/blank lines [BZ #18887]
The fix for BZ #17273 introduced a single byte of memory corruption when
the line is entirely blank.  It would walk back past the start of the
buffer if the heap happened to be 0x20 or 0x09 and then write a NUL byte.
	buffer = '\n';
	end_ptr = buffer;
	while (end_ptr[-1] == ' ' || end_ptr[-1] == '\t')
		end_ptr--;
	*end_ptr = '\0';

Fix that and rework the tests.  Adding the testcase for BZ #17273 to the
existing \040 parser does not really make sense as it's unrelated, and
leads to confusing behavior: it implicitly relies on the new entry being
longer than the previous entry (since it just rewinds the FILE*).  Split
it out into its own dedicated testcase instead.

(cherry picked from commit b0e805fa0d)
2015-08-29 18:12:23 -04:00
Mike Frysinger 978908245b ia64: atomic.h: fix atomic_exchange_and_add 64bit handling
Way back in 2005 the atomic_exchange_and_add function was cleaned up to
avoid the explicit size checking and instead let gcc handle things itself.
Unfortunately that change ended up leaving beyond a cast to int, even when
the incoming value was a long.  This has flown under the radar for a long
time due to the function not being heavily used in the tree (especially as
a full 64bit field), but a recent change to semaphores made some nptl tests
fail reliably.  This is due to the code packing two 32bit values into one
64bit variable (where the high 32bits contained the number of waiters), and
then the whole variable being atomically updated between threads.  On ia64,
that meant we never atomically updated the count, so sometimes the sem_post
would not wake up the waiters.

(cherry picked from commit cf31a2c799)
2015-07-28 05:03:27 -04:00
Paul Pluzhnikov 8a4e5cc657 Fix BZ #17269 -- _IO_wstr_overflow integer overflow
(cherry picked from commit bdf1ff052a)
2015-07-20 22:35:37 -04:00
Andreas Schwab fe7b1136e5 Fix read past end of pattern in fnmatch (bug 18032)
(cherry picked from commit 4a28f4d55a)
2015-07-20 22:19:12 -04:00
Mike Frysinger d679497db2 sparc: fix sigaction for 32bit builds [BZ #18694]
Commit a059d359d8 changed the sigaction
struct to pass conform tests, but it ended up also changing the ABI for
32 bit builds.  For 64 bit builds, changing the long to two ints works,
but for 32 bit builds, it inserts 4 extra bytes.  This leads to many
packages randomly failing like bash that spews things like:
	configure: line 471: wait_for: No record of process 0

Bracket the new member by a wordsize check to fix the ABI for 32bit.

(cherry picked from commit 7fde904c73)
2015-07-20 21:59:58 -04:00
Arjun Shankar 01b07c70ad CVE-2015-1781: resolv/nss_dns/dns-host.c buffer overflow [BZ#18287]
(cherry picked from commit 2959eda927)
2015-04-22 20:01:12 +10:00
Evangelos Foutras 75adf430d2 Fix __memcpy_chk on non-SSE2 CPUs
In commit 8b4416d, the 1: jump label in __mempcpy_chk was accidentally
moved.  This resulted in failures of mempcpy on CPU without SSE2.

(cherry picked from commit 132a1328ec)
2015-02-10 21:43:02 +10:00
Florian Weimer c66e8b9e58 NEWS: Also mention CVE-2015-1473 2015-02-06 16:30:15 +01:00
Carlos O'Donell 004c993bdd Fix missing ChangeLog attribution. 2015-02-06 02:00:52 -05:00
57 changed files with 2037 additions and 476 deletions
+223
View File
@@ -1,3 +1,225 @@
2016-05-09 Yvan Roux <yvan.roux@linaro.org>
* stdlib/setenv.c (unsetenv): Fix ambiguous 'else'.
* nis/nis_call.c (nis_server_cache_add): Likewise.
2016-04-28 Stefan Liebler <stli@linux.vnet.ibm.com>
[BZ #18508]
* stdlib/Makefile ($(objpfx)tst-makecontext3):
Depend on $(libdl).
* stdlib/tst-makecontext.c (cf): Test if _Unwind_Backtrace
is not called infinitely times.
(backtrace_helper): New function.
(trace_arg): New struct.
(st1): Enlarge stack size.
* sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S:
(__makecontext_ret): Omit cfi_startproc and cfi_endproc.
* sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S:
Likewise.
2016-04-28 Stefan Liebler <stli@linux.vnet.ibm.com>
[BZ #18080]
* sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S
(__setcontext): Use SIG_SETMASK instead of SIG_BLOCK.
* sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S
(__setcontext): Likewise.
* sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S
(__swapcontext): Use SIG_SETMASK instead of SIG_BLOCK.
Call rt_sigprocmask syscall one time to set new signal mask
and retrieve the current signal mask instead of two calls.
* sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S
(__swapcontext): Likewise.
* stdlib/Makefile (tests): Add new testcase tst-setcontext2.
* stdlib/tst-setcontext2.c: New file.
2016-04-09 Mike Frysinger <vapier@gentoo.org>
* sysdeps/x86_64/configure.ac: Change == to = when calling test.
* sysdeps/x86_64/configure: Likewise.
2016-04-04 Stefan Liebler <stli@linux.vnet.ibm.com>
* sysdeps/s390/bits/link.h: (La_s390_vr) New typedef.
(La_s390_32_regs): Append vector register lr_v24-lr_v31.
(La_s390_64_regs): Likewise.
(La_s390_32_retval): Append vector register lrv_v24.
(La_s390_64_retval): Likeweise.
* sysdeps/s390/s390-32/dl-trampoline.h (_dl_runtime_profile):
Handle extended structs La_s390_32_regs and La_s390_32_retval.
* sysdeps/s390/s390-64/dl-trampoline.h (_dl_runtime_profile):
Handle extended structs La_s390_64_regs and La_s390_64_retval.
2016-04-04 Stefan Liebler <stli@linux.vnet.ibm.com>
* sysdeps/s390/s390-32/dl-trampoline.S: Include dl-trampoline.h twice
to create a non-vector/vector version for _dl_runtime_resolve and
_dl_runtime_profile. Move implementation to ...
* sysdeps/s390/s390-32/dl-trampoline.h: ... here.
(_dl_runtime_resolve) Save and restore fpr/vrs.
(_dl_runtime_profile) Save and restore vrs and fix some issues
if _dl_call_pltexit is called.
* sysdeps/s390/s390-32/dl-machine.h (elf_machine_runtime_setup):
Choose the correct resolver function if running on a machine with vx.
* sysdeps/s390/s390-64/dl-trampoline.S: Include dl-trampoline.h twice
to create a non-vector/vector version for _dl_runtime_resolve and
_dl_runtime_profile. Move implementation to ...
* sysdeps/s390/s390-64/dl-trampoline.h: ... here.
(_dl_runtime_resolve) Save and restore fpr/vrs.
(_dl_runtime_profile) Save and restore vrs and fix some issues
* sysdeps/s390/s390-64/dl-machine.h: (elf_machine_runtime_setup):
Choose the correct resolver function if running on a machine with vx.
2016-04-04 Stefan Liebler <stli@linux.vnet.ibm.com>
* config.h.in (HAVE_S390_VX_ASM_SUPPORT): New macro undefine.
* sysdeps/s390/configure.ac: Add test for S390 vector instruction
assembler support.
* sysdeps/s390/configure: Regenerated.
2016-04-04 Stefan Liebler <stli@linux.vnet.ibm.com>
* sysdeps/s390/dl-procinfo.c (_dl_s390_cap_flags): Add z13.
* sysdeps/s390/dl-procinfo.h (_DL_PLATFORMS_COUNT): Increased.
2016-04-04 Stefan Liebler <stli@linux.vnet.ibm.com>
* sysdeps/s390/dl-procinfo.c (_dl_s390_platforms): Add vector flag.
* sysdeps/s390/dl-procinfo.h: Add vector capability.
* sysdeps/unix/sysv/linux/s390/bits/hwcap.h (HWCAP_S390_VX): Define.
2016-03-07 Hongjiu Zhang <noctuorare@gmail.com>
* elf/sln.c (makesymlink): Change struct stat to stat64, and lstat
to lstat64.
2016-03-02 Stefan Liebler <stli@linux.vnet.ibm.com>
[BZ #19682]
* sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list:
Remove socketcall syscalls.
2016-02-15 Carlos O'Donell <carlos@redhat.com>
[BZ #18665]
* resolv/nss_dns/dns-host.c (gaih_getanswer_slice): Always set
*herrno_p.
(gaih_getanswer): Document functional behviour. Return tryagain
if any result is tryagain.
* resolv/res_query.c (__libc_res_nsearch): Set buffer size to zero
when freed.
* resolv/res_send.c: Add copyright text.
(__libc_res_nsend): Document that MAXPACKET is expected.
(send_vc): Document. Remove buffer reuse.
(send_dg): Document. Remove buffer reuse. Set *thisanssizp to set the
size of the buffer. Add Dprint for truncated UDP buffer.
2016-02-12 Florian Weimer <fweimer@redhat.com>
* misc/bug18240.c (do_test): Set RLIMIT_AS.
2016-01-27 Paul Eggert <eggert@cs.ucla.edu>
[BZ #18240]
* misc/hsearch_r.c (isprime, __hcreate_r): Protect against
unsigned int wraparound.
2016-01-27 Florian Weimer <fweimer@redhat.com>
[BZ #18240]
* misc/bug18240.c: New test.
* misc/Makefile (tests): Add it.
2015-08-25 Ondřej Bílka <neleai@seznam.cz>
[BZ #18240]
* misc/hsearch_r.c (__hcreate_r): Handle overflow.
2015-09-26 Paul Pluzhnikov <ppluzhnikov@google.com>
[BZ #18985]
* time/strftime_l.c (a_wkday, f_wkday, a_month, f_month): Range check.
(__strftime_internal): Likewise.
* time/tst-strftime.c (do_bz18985): New test.
(do_test): Call it.
2015-08-08 Paul Pluzhnikov <ppluzhnikov@google.com>
[BZ #17905]
* catgets/Makefile (tst-catgets-mem): New test.
* catgets/catgets.c (catopen): Don't use unbounded alloca.
* catgets/open_catalog.c (__open_catalog): Likewise.
* catgets/tst-catgets.c (do_bz17905): Test unbounded alloca.
2015-05-01 Szabolcs Nagy <szabolcs.nagy@arm.com>
* config.h.in (HAVE_AARCH64_BE): Add.
2015-07-08 Mike Frysinger <vapier@gentoo.org>
* nscd/selinux.c: Delete selinux/flask.h include.
2015-03-02 Andreas Schwab <schwab@suse.de>
* elf/Makefile ($(elf-objpfx)runtime-linker.st): Fix typo in
variable name.
2015-04-29 Florian Weimer <fweimer@redhat.com>
[BZ #18007]
* nss/nss_files/files-XXX.c (CONCAT): Always enable stayopen.
(CVE-2014-8121)
* nss/tst-nss-getpwent.c: New file.
* nss/Makefile (tests): Add new test.
2015-08-28 Mike Frysinger <vapier@gentoo.org>
[BZ #18887]
* misc/Makefile (tests): Add tst-mntent-blank-corrupt and
tst-mntent-blank-passno.
* misc/mntent_r.c (__getmntent_r): Do not read past buffer[0].
* misc/tst-mntent-blank-corrupt.c: New test.
* misc/tst-mntent-blank-passno.c: New test ripped from ...
* misc/tst-mntent.c (do_test): ... here.
2015-07-27 Mike Frysinger <vapier@gentoo.org>
* sysdeps/ia64/bits/atomic.h (atomic_exchange_and_add): Define
directly in terms of __sync_fetch_and_add and delete (int) cast.
2015-02-22 Paul Pluzhnikov <ppluzhnikov@google.com>
[BZ #17269]
* libio/wstrops.c (_IO_wstr_overflow): Guard against integer overflow
(enlarge_userbuf): Likewise.
2015-02-26 Andreas Schwab <schwab@suse.de>
[BZ #18032]
* posix/fnmatch_loop.c (FCT): Remove extra increment when skipping
over collating symbol inside a bracket expression. Minor cleanup.
* posix/tst-fnmatch3.c (do_test): Add test case.
2015-07-21 Mike Frysinger <vapier@gentoo.org>
[BZ #18694]
* sysdeps/unix/sysv/linux/sparc/bits/sigaction.h: Include
bits/wordsize.h.
(sigaction): Declare __glibc_reserved0 only when __WORDSIZE is 64.
2015-04-21 Arjun Shankar <arjun.is@lostca.se>
[BZ #18287]
* resolv/nss_dns/dns-host.c (getanswer_r): Adjust buffer length
based on padding. (CVE-2015-1781)
2015-02-10 Evangelos Foutras <evangelos@foutrelis.com>
[BZ #17949]
* sysdeps/i386/i686/multiarch/mempcpy_chk.S: Fix position of
jump label.
2015-02-06 Carlos O'Donell <carlos@systemhalted.org>
* version.h (RELEASE): Set to "stable".
@@ -7,6 +229,7 @@
* sysdeps/unix/sysv/linux/hppa/pthread.h: Sync with pthread.h.
2015-02-05 Paul Pluzhnikov <ppluzhnikov@google.com>
Paul Eggert <eggert@cs.ucla.edu>
[BZ #16618]
* stdio-common/tst-sscanf.c (main): Test for buffer overflow.
+42 -4
View File
@@ -5,6 +5,43 @@ See the end for copying conditions.
Please send GNU C library bug reports via <http://sourceware.org/bugzilla/>
using `glibc' in the "product" field.
Version 2.21.1
* The following bugs are resolved with this release:
17269, 17905, 17949, 18007, 18032, 18080, 18240, 18287, 18508, 18694,
18887, 18985, 19682.
* A stack-based buffer overflow was found in libresolv when invoked from
libnss_dns, allowing specially crafted DNS responses to seize control
of execution flow in the DNS client. The buffer overflow occurs in
the functions send_dg (send datagram) and send_vc (send TCP) for the
NSS module libnss_dns.so.2 when calling getaddrinfo with AF_UNSPEC
family. The use of AF_UNSPEC triggers the low-level resolver code to
send out two parallel queries for A and AAAA. A mismanagement of the
buffers used for those queries could result in the response of a query
writing beyond the alloca allocated buffer created by
_nss_dns_gethostbyname4_r. Buffer management is simplified to remove
the overflow. Thanks to the Google Security Team and Red Hat for
reporting the security impact of this issue, and Robert Holiday of
Ciena for reporting the related bug 18665. (CVE-2015-7547)
* A buffer overflow in gethostbyname_r and related functions performing DNS
requests has been fixed. If the NSS functions were called with a
misaligned buffer, the buffer length change due to pointer alignment was
not taken into account. This could result in application crashes or,
potentially arbitrary code execution, using crafted, but syntactically
valid DNS responses. (CVE-2015-1781)
* The 32-bit sparc sigaction ABI was inadvertently broken in the 2.20 and 2.21
releases. It has been fixed to match 2.19 and older, but binaries built
against 2.20 and 2.21 might need to be recompiled. See BZ#18694.
* CVE-2014-8121 The NSS files backend would reset the file pointer used by
the get*ent functions if any of the query functions for the same database
are used during the iteration, causing a denial-of-service condition in
some applications.
Version 2.21
* The following bugs are resolved with this release:
@@ -21,10 +58,11 @@ Version 2.21
17801, 17803, 17806, 17834, 17844, 17848, 17868, 17869, 17870, 17885,
17892.
* CVE-2015-1472 Under certain conditions wscanf can allocate too little
memory for the to-be-scanned arguments and overflow the allocated
buffer. The implementation now correctly computes the required buffer
size when using malloc.
* CVE-2015-1472 CVE-2015-1473 Under certain conditions wscanf can allocate
too little memory for the to-be-scanned arguments and overflow the
allocated buffer. The implementation now correctly computes the required
buffer size when using malloc, and switches to malloc from alloca as
intended.
* A new semaphore algorithm has been implemented in generic C code for all
machines. Previous custom assembly implementations of semaphore were
+8 -1
View File
@@ -34,6 +34,7 @@ test-srcs = test-gencat
ifeq ($(run-built-tests),yes)
tests-special += $(objpfx)de/libc.cat $(objpfx)test1.cat $(objpfx)test2.cat \
$(objpfx)sample.SJIS.cat $(objpfx)test-gencat.out
tests-special += $(objpfx)tst-catgets-mem.out
endif
gencat-modules = xmalloc
@@ -50,9 +51,11 @@ catgets-CPPFLAGS := -DNLSPATH='"$(msgcatdir)/%L/%N:$(msgcatdir)/%L/LC_MESSAGES/%
generated += de.msg test1.cat test1.h test2.cat test2.h sample.SJIS.cat \
test-gencat.h
generated += tst-catgets.mtrace tst-catgets-mem.out
generated-dirs += de
tst-catgets-ENV = NLSPATH="$(objpfx)%l/%N.cat" LANG=de
tst-catgets-ENV = NLSPATH="$(objpfx)%l/%N.cat" LANG=de MALLOC_TRACE=$(objpfx)tst-catgets.mtrace
ifeq ($(run-built-tests),yes)
# This test just checks whether the program produces any error or not.
@@ -86,4 +89,8 @@ $(objpfx)test-gencat.out: test-gencat.sh $(objpfx)test-gencat \
$(objpfx)sample.SJIS.cat: sample.SJIS $(objpfx)gencat
$(built-program-cmd) -H $(objpfx)test-gencat.h < $(word 1,$^) > $@; \
$(evaluate-test)
$(objpfx)tst-catgets-mem.out: $(objpfx)tst-catgets.out
$(common-objpfx)malloc/mtrace $(objpfx)tst-catgets.mtrace > $@; \
$(evaluate-test)
endif
+12 -7
View File
@@ -16,7 +16,6 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <alloca.h>
#include <errno.h>
#include <locale.h>
#include <nl_types.h>
@@ -35,6 +34,7 @@ catopen (const char *cat_name, int flag)
__nl_catd result;
const char *env_var = NULL;
const char *nlspath = NULL;
char *tmp = NULL;
if (strchr (cat_name, '/') == NULL)
{
@@ -54,7 +54,10 @@ catopen (const char *cat_name, int flag)
{
/* Append the system dependent directory. */
size_t len = strlen (nlspath) + 1 + sizeof NLSPATH;
char *tmp = alloca (len);
tmp = malloc (len);
if (__glibc_unlikely (tmp == NULL))
return (nl_catd) -1;
__stpcpy (__stpcpy (__stpcpy (tmp, nlspath), ":"), NLSPATH);
nlspath = tmp;
@@ -65,16 +68,18 @@ catopen (const char *cat_name, int flag)
result = (__nl_catd) malloc (sizeof (*result));
if (result == NULL)
/* We cannot get enough memory. */
return (nl_catd) -1;
if (__open_catalog (cat_name, nlspath, env_var, result) != 0)
{
/* We cannot get enough memory. */
result = (nl_catd) -1;
}
else if (__open_catalog (cat_name, nlspath, env_var, result) != 0)
{
/* Couldn't open the file. */
free ((void *) result);
return (nl_catd) -1;
result = (nl_catd) -1;
}
free (tmp);
return (nl_catd) result;
}
+14 -9
View File
@@ -47,6 +47,7 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var,
size_t tab_size;
const char *lastp;
int result = -1;
char *buf = NULL;
if (strchr (cat_name, '/') != NULL || nlspath == NULL)
fd = open_not_cancel_2 (cat_name, O_RDONLY);
@@ -57,23 +58,23 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var,
if (__glibc_unlikely (bufact + (n) >= bufmax)) \
{ \
char *old_buf = buf; \
bufmax += 256 + (n); \
buf = (char *) alloca (bufmax); \
memcpy (buf, old_buf, bufact); \
bufmax += (bufmax < 256 + (n)) ? 256 + (n) : bufmax; \
buf = realloc (buf, bufmax); \
if (__glibc_unlikely (buf == NULL)) \
{ \
free (old_buf); \
return -1; \
} \
}
/* The RUN_NLSPATH variable contains a colon separated list of
descriptions where we expect to find catalogs. We have to
recognize certain % substitutions and stop when we found the
first existing file. */
char *buf;
size_t bufact;
size_t bufmax;
size_t bufmax = 0;
size_t len;
buf = NULL;
bufmax = 0;
fd = -1;
while (*run_nlspath != '\0')
{
@@ -188,7 +189,10 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var,
/* Avoid dealing with directories and block devices */
if (__builtin_expect (fd, 0) < 0)
return -1;
{
free (buf);
return -1;
}
if (__builtin_expect (__fxstat64 (_STAT_VER, fd, &st), 0) < 0)
goto close_unlock_return;
@@ -325,6 +329,7 @@ __open_catalog (const char *cat_name, const char *nlspath, const char *env_var,
/* Release the lock again. */
close_unlock_return:
close_not_cancel_no_status (fd);
free (buf);
return result;
}
+31
View File
@@ -1,7 +1,10 @@
#include <assert.h>
#include <mcheck.h>
#include <nl_types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/resource.h>
static const char *msgs[] =
@@ -12,6 +15,33 @@ static const char *msgs[] =
};
#define nmsgs (sizeof (msgs) / sizeof (msgs[0]))
/* Test for unbounded alloca. */
static int
do_bz17905 (void)
{
char *buf;
struct rlimit rl;
nl_catd result;
const int sz = 1024 * 1024;
getrlimit (RLIMIT_STACK, &rl);
rl.rlim_cur = sz;
setrlimit (RLIMIT_STACK, &rl);
buf = malloc (sz + 1);
memset (buf, 'A', sz);
buf[sz] = '\0';
setenv ("NLSPATH", buf, 1);
result = catopen (buf, NL_CAT_LOCALE);
assert (result == (nl_catd) -1);
free (buf);
return 0;
}
#define ROUNDS 5
static int
@@ -62,6 +92,7 @@ do_test (void)
}
}
result += do_bz17905 ();
return result;
}
+6
View File
@@ -94,6 +94,9 @@
/* Define if assembler supports AVX512. */
#undef HAVE_AVX512_ASM_SUPPORT
/* Define if assembler supports vector instructions on S390. */
#undef HAVE_S390_VX_ASM_SUPPORT
/* Define if assembler supports Intel MPX. */
#undef HAVE_MPX_SUPPORT
@@ -114,6 +117,9 @@
include/libc-symbols.h that avoid PLT slots in the shared objects. */
#undef NO_HIDDEN
/* AArch64 big endian ABI */
#undef HAVE_AARCH64_BE
/* Defined to some form of __attribute__ ((...)) if the compiler supports
a different, more efficient calling convention. */
+1 -1
View File
@@ -358,7 +358,7 @@ $(objpfx)interp.os: $(elf-objpfx)runtime-linker.h
$(elf-objpfx)runtime-linker.h: $(elf-objpfx)runtime-linker.st; @:
$(elf-objpfx)runtime-linker.st: $(common-objpfx)config.make
$(name-target-directory)
$(make-target-directory)
echo '#define RUNTIME_LINKER "$(rtlddir)/$(rtld-installed-name)"' \
> ${@:st=T}
$(move-if-change) ${@:st=T} ${@:st=h}
+2 -2
View File
@@ -167,11 +167,11 @@ makesymlink (src, dest)
const char *src;
const char *dest;
{
struct stat stats;
struct stat64 stats;
const char *error;
/* Destination must not be a directory. */
if (lstat (dest, &stats) == 0)
if (lstat64 (dest, &stats) == 0)
{
if (S_ISDIR (stats.st_mode))
{
+7 -1
View File
@@ -95,8 +95,11 @@ _IO_wstr_overflow (fp, c)
wchar_t *old_buf = fp->_wide_data->_IO_buf_base;
size_t old_wblen = _IO_wblen (fp);
_IO_size_t new_size = 2 * old_wblen + 100;
if (new_size < old_wblen)
if (__glibc_unlikely (new_size < old_wblen)
|| __glibc_unlikely (new_size > SIZE_MAX / sizeof (wchar_t)))
return EOF;
new_buf
= (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size
* sizeof (wchar_t));
@@ -186,6 +189,9 @@ enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading)
return 1;
_IO_size_t newsize = offset + 100;
if (__glibc_unlikely (newsize > SIZE_MAX / sizeof (wchar_t)))
return 1;
wchar_t *oldbuf = wd->_IO_buf_base;
wchar_t *newbuf
= (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize
+2 -1
View File
@@ -76,7 +76,8 @@ install-lib := libg.a
gpl2lgpl := error.c error.h
tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \
tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1
tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1 \
tst-mntent-blank-corrupt tst-mntent-blank-passno bug18240
ifeq ($(run-built-tests),yes)
tests-special += $(objpfx)tst-error1-mem.out
endif
+97
View File
@@ -0,0 +1,97 @@
/* Test integer wraparound in hcreate.
Copyright (C) 2016 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 <errno.h>
#include <limits.h>
#include <search.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>
static void
test_size (size_t size)
{
int res = hcreate (size);
if (res == 0)
{
if (errno == ENOMEM)
return;
printf ("error: hcreate (%zu): %m\n", size);
exit (1);
}
char *keys[100];
for (int i = 0; i < 100; ++i)
{
if (asprintf (keys + i, "%d", i) < 0)
{
printf ("error: asprintf: %m\n");
exit (1);
}
ENTRY e = { keys[i], (char *) "value" };
if (hsearch (e, ENTER) == NULL)
{
printf ("error: hsearch (\"%s\"): %m\n", keys[i]);
exit (1);
}
}
hdestroy ();
for (int i = 0; i < 100; ++i)
free (keys[i]);
}
static int
do_test (void)
{
/* Limit the size of the process, so that memory allocation will
fail without impacting the entire system. */
{
struct rlimit limit;
if (getrlimit (RLIMIT_AS, &limit) != 0)
{
printf ("getrlimit (RLIMIT_AS) failed: %m\n");
return 1;
}
long target = 100 * 1024 * 1024;
if (limit.rlim_cur == RLIM_INFINITY || limit.rlim_cur > target)
{
limit.rlim_cur = target;
if (setrlimit (RLIMIT_AS, &limit) != 0)
{
printf ("setrlimit (RLIMIT_AS) failed: %m\n");
return 1;
}
}
}
test_size (500);
test_size (-1);
test_size (-3);
test_size (INT_MAX - 2);
test_size (INT_MAX - 1);
test_size (INT_MAX);
test_size (((unsigned) INT_MAX) + 1);
test_size (UINT_MAX - 2);
test_size (UINT_MAX - 1);
test_size (UINT_MAX);
return 0;
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
+18 -12
View File
@@ -19,7 +19,7 @@
#include <errno.h>
#include <malloc.h>
#include <string.h>
#include <stdint.h>
#include <search.h>
/* [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
@@ -46,15 +46,12 @@ static int
isprime (unsigned int number)
{
/* no even number will be passed */
unsigned int div = 3;
while (div * div < number && number % div != 0)
div += 2;
return number % div != 0;
for (unsigned int div = 3; div <= number / div; div += 2)
if (number % div == 0)
return 0;
return 1;
}
/* Before using the hash table we must allocate memory for it.
Test for an existing table are done. We allocate one element
more as the found prime number says. This is done for more effective
@@ -81,10 +78,19 @@ hcreate_r (nel, htab)
use will not work. */
if (nel < 3)
nel = 3;
/* Change nel to the first prime number not smaller as nel. */
nel |= 1; /* make odd */
while (!isprime (nel))
nel += 2;
/* Change nel to the first prime number in the range [nel, UINT_MAX - 2],
The '- 2' means 'nel += 2' cannot overflow. */
for (nel |= 1; ; nel += 2)
{
if (UINT_MAX - 2 < nel)
{
__set_errno (ENOMEM);
return 0;
}
if (isprime (nel))
break;
}
htab->size = nel;
htab->filled = 0;
+3 -1
View File
@@ -136,7 +136,9 @@ __getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)
end_ptr = strchr (buffer, '\n');
if (end_ptr != NULL) /* chop newline */
{
while (end_ptr[-1] == ' ' || end_ptr[-1] == '\t')
/* Do not walk past the start of buffer if it's all whitespace. */
while (end_ptr != buffer
&& (end_ptr[-1] == ' ' || end_ptr[-1] == '\t'))
end_ptr--;
*end_ptr = '\0';
}
+45
View File
@@ -0,0 +1,45 @@
/* Make sure blank lines does not cause memory corruption BZ #18887.
Copyright (C) 2009-2015 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 <mntent.h>
#include <stdio.h>
#include <string.h>
/* Make sure blank lines don't trigger memory corruption. This doesn't happen
for all targets though, so it's a best effort test BZ #18887. */
static int
do_test (void)
{
FILE *fp;
fp = tmpfile ();
fputs ("\n \n/foo\\040dir /bar\\040dir auto bind \t \n", fp);
rewind (fp);
/* The corruption happens here ... */
getmntent (fp);
/* ... but trigers here. */
endmntent (fp);
/* If the test failed, we would crash, and not hit this point. */
return 0;
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
+53
View File
@@ -0,0 +1,53 @@
/* Make sure trailing whitespace is handled properly BZ #17273.
Copyright (C) 2009-2015 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 <mntent.h>
#include <stdio.h>
#include <string.h>
/* Check entries to make sure trailing whitespace is ignored and we return the
correct passno value BZ #17273. */
static int
do_test (void)
{
int result = 0;
FILE *fp;
struct mntent *mnt;
fp = tmpfile ();
fputs ("/foo\\040dir /bar\\040dir auto bind \t \n", fp);
rewind (fp);
mnt = getmntent (fp);
if (strcmp (mnt->mnt_fsname, "/foo dir") != 0
|| strcmp (mnt->mnt_dir, "/bar dir") != 0
|| strcmp (mnt->mnt_type, "auto") != 0
|| strcmp (mnt->mnt_opts, "bind") != 0
|| mnt->mnt_freq != 0
|| mnt->mnt_passno != 0)
{
puts ("Error while reading entry with trailing whitespaces");
result = 1;
}
return result;
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
-20
View File
@@ -73,26 +73,6 @@ main (int argc, char *argv[])
puts ("Error while reading written entry back in");
result = 1;
}
/* Part III: Entry with whitespaces at the end of a line. */
rewind (fp);
fputs ("/foo\\040dir /bar\\040dir auto bind \t \n", fp);
rewind (fp);
mnt = getmntent (fp);
if (strcmp (mnt->mnt_fsname, "/foo dir") != 0
|| strcmp (mnt->mnt_dir, "/bar dir") != 0
|| strcmp (mnt->mnt_type, "auto") != 0
|| strcmp (mnt->mnt_opts, "bind") != 0
|| mnt->mnt_freq != 0
|| mnt->mnt_passno != 0)
{
puts ("Error while reading entry with trailing whitespaces");
result = 1;
}
}
return result;
+11 -9
View File
@@ -680,16 +680,18 @@ nis_server_cache_add (const_nis_name name, int search_parent,
/* Choose which entry should be evicted from the cache. */
loc = &nis_server_cache[0];
if (*loc != NULL)
for (i = 1; i < 16; ++i)
if (nis_server_cache[i] == NULL)
{
{
for (i = 1; i < 16; ++i)
if (nis_server_cache[i] == NULL)
{
loc = &nis_server_cache[i];
break;
}
else if ((*loc)->uses > nis_server_cache[i]->uses
|| ((*loc)->uses == nis_server_cache[i]->uses
&& (*loc)->expires > nis_server_cache[i]->expires))
loc = &nis_server_cache[i];
break;
}
else if ((*loc)->uses > nis_server_cache[i]->uses
|| ((*loc)->uses == nis_server_cache[i]->uses
&& (*loc)->expires > nis_server_cache[i]->expires))
loc = &nis_server_cache[i];
}
old = *loc;
*loc = new;
-1
View File
@@ -29,7 +29,6 @@
#include <unistd.h>
#include <sys/prctl.h>
#include <selinux/avc.h>
#include <selinux/flask.h>
#include <selinux/selinux.h>
#ifdef HAVE_LIBAUDIT
# include <libaudit.h>
+1 -1
View File
@@ -39,7 +39,7 @@ install-bin := getent makedb
makedb-modules = xmalloc hash-string
extra-objs += $(makedb-modules:=.o)
tests = test-netdb tst-nss-test1 test-digits-dots
tests = test-netdb tst-nss-test1 test-digits-dots tst-nss-getpwent
xtests = bug-erange
# Specify rules for the nss_* modules. We have some services.
+1 -1
View File
@@ -134,7 +134,7 @@ CONCAT(_nss_files_set,ENTNAME) (int stayopen)
__libc_lock_lock (lock);
status = internal_setent (stayopen);
status = internal_setent (1);
if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
{
+118
View File
@@ -0,0 +1,118 @@
/* Copyright (C) 2015 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 <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
do_test (void)
{
/* Count the number of entries in the password database, and fetch
data from the first and last entries. */
size_t count = 0;
struct passwd * pw;
char *first_name = NULL;
uid_t first_uid = 0;
char *last_name = NULL;
uid_t last_uid = 0;
setpwent ();
while ((pw = getpwent ()) != NULL)
{
if (first_name == NULL)
{
first_name = strdup (pw->pw_name);
if (first_name == NULL)
{
printf ("strdup: %m\n");
return 1;
}
first_uid = pw->pw_uid;
}
free (last_name);
last_name = strdup (pw->pw_name);
if (last_name == NULL)
{
printf ("strdup: %m\n");
return 1;
}
last_uid = pw->pw_uid;
++count;
}
endpwent ();
if (count == 0)
{
printf ("No entries in the password database.\n");
return 0;
}
/* Try again, this time interleaving with name-based and UID-based
lookup operations. The counts do not match if the interleaved
lookups affected the enumeration. */
size_t new_count = 0;
setpwent ();
while ((pw = getpwent ()) != NULL)
{
if (new_count == count)
{
printf ("Additional entry in the password database.\n");
return 1;
}
++new_count;
struct passwd *pw2 = getpwnam (first_name);
if (pw2 == NULL)
{
printf ("getpwnam (%s) failed: %m\n", first_name);
return 1;
}
pw2 = getpwnam (last_name);
if (pw2 == NULL)
{
printf ("getpwnam (%s) failed: %m\n", last_name);
return 1;
}
pw2 = getpwuid (first_uid);
if (pw2 == NULL)
{
printf ("getpwuid (%llu) failed: %m\n",
(unsigned long long) first_uid);
return 1;
}
pw2 = getpwuid (last_uid);
if (pw2 == NULL)
{
printf ("getpwuid (%llu) failed: %m\n",
(unsigned long long) last_uid);
return 1;
}
}
endpwent ();
if (new_count < count)
{
printf ("Missing entry in the password database.\n");
return 1;
}
return 0;
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
+2 -3
View File
@@ -945,14 +945,13 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
}
else if (c == L('[') && *p == L('.'))
{
++p;
while (1)
{
c = *++p;
if (c == '\0')
if (c == L('\0'))
return FNM_NOMATCH;
if (*p == L('.') && p[1] == L(']'))
if (c == L('.') && p[1] == L(']'))
break;
}
p += 2;
+5 -3
View File
@@ -21,9 +21,11 @@
int
do_test (void)
{
const char *pattern = "[[:alpha:]'[:alpha:]\0]";
return fnmatch (pattern, "a", 0) != FNM_NOMATCH;
if (fnmatch ("[[:alpha:]'[:alpha:]\0]", "a", 0) != FNM_NOMATCH)
return 1;
if (fnmatch ("[a[.\0.]]", "a", 0) != FNM_NOMATCH)
return 1;
return 0;
}
#define TEST_FUNCTION do_test ()
+111 -3
View File
@@ -615,7 +615,8 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
int have_to_map = 0;
uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
buffer += pad;
if (__glibc_unlikely (buflen < sizeof (struct host_data) + pad))
buflen = buflen > pad ? buflen - pad : 0;
if (__glibc_unlikely (buflen < sizeof (struct host_data)))
{
/* The buffer is too small. */
too_small:
@@ -1031,7 +1032,10 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
int h_namelen = 0;
if (ancount == 0)
return NSS_STATUS_NOTFOUND;
{
*h_errnop = HOST_NOT_FOUND;
return NSS_STATUS_NOTFOUND;
}
while (ancount-- > 0 && cp < end_of_message && had_error == 0)
{
@@ -1208,7 +1212,14 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
/* Special case here: if the resolver sent a result but it only
contains a CNAME while we are looking for a T_A or T_AAAA record,
we fail with NOTFOUND instead of TRYAGAIN. */
return canon == NULL ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND;
if (canon != NULL)
{
*h_errnop = HOST_NOT_FOUND;
return NSS_STATUS_NOTFOUND;
}
*h_errnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
@@ -1222,11 +1233,101 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
enum nss_status status = NSS_STATUS_NOTFOUND;
/* Combining the NSS status of two distinct queries requires some
compromise and attention to symmetry (A or AAAA queries can be
returned in any order). What follows is a breakdown of how this
code is expected to work and why. We discuss only SUCCESS,
TRYAGAIN, NOTFOUND and UNAVAIL, since they are the only returns
that apply (though RETURN and MERGE exist). We make a distinction
between TRYAGAIN (recoverable) and TRYAGAIN' (not-recoverable).
A recoverable TRYAGAIN is almost always due to buffer size issues
and returns ERANGE in errno and the caller is expected to retry
with a larger buffer.
Lastly, you may be tempted to make significant changes to the
conditions in this code to bring about symmetry between responses.
Please don't change anything without due consideration for
expected application behaviour. Some of the synthesized responses
aren't very well thought out and sometimes appear to imply that
IPv4 responses are always answer 1, and IPv6 responses are always
answer 2, but that's not true (see the implementation of send_dg
and send_vc to see response can arrive in any order, particularly
for UDP). However, we expect it holds roughly enough of the time
that this code works, but certainly needs to be fixed to make this
a more robust implementation.
----------------------------------------------
| Answer 1 Status / | Synthesized | Reason |
| Answer 2 Status | Status | |
|--------------------------------------------|
| SUCCESS/SUCCESS | SUCCESS | [1] |
| SUCCESS/TRYAGAIN | TRYAGAIN | [5] |
| SUCCESS/TRYAGAIN' | SUCCESS | [1] |
| SUCCESS/NOTFOUND | SUCCESS | [1] |
| SUCCESS/UNAVAIL | SUCCESS | [1] |
| TRYAGAIN/SUCCESS | TRYAGAIN | [2] |
| TRYAGAIN/TRYAGAIN | TRYAGAIN | [2] |
| TRYAGAIN/TRYAGAIN' | TRYAGAIN | [2] |
| TRYAGAIN/NOTFOUND | TRYAGAIN | [2] |
| TRYAGAIN/UNAVAIL | TRYAGAIN | [2] |
| TRYAGAIN'/SUCCESS | SUCCESS | [3] |
| TRYAGAIN'/TRYAGAIN | TRYAGAIN | [3] |
| TRYAGAIN'/TRYAGAIN' | TRYAGAIN' | [3] |
| TRYAGAIN'/NOTFOUND | TRYAGAIN' | [3] |
| TRYAGAIN'/UNAVAIL | UNAVAIL | [3] |
| NOTFOUND/SUCCESS | SUCCESS | [3] |
| NOTFOUND/TRYAGAIN | TRYAGAIN | [3] |
| NOTFOUND/TRYAGAIN' | TRYAGAIN' | [3] |
| NOTFOUND/NOTFOUND | NOTFOUND | [3] |
| NOTFOUND/UNAVAIL | UNAVAIL | [3] |
| UNAVAIL/SUCCESS | UNAVAIL | [4] |
| UNAVAIL/TRYAGAIN | UNAVAIL | [4] |
| UNAVAIL/TRYAGAIN' | UNAVAIL | [4] |
| UNAVAIL/NOTFOUND | UNAVAIL | [4] |
| UNAVAIL/UNAVAIL | UNAVAIL | [4] |
----------------------------------------------
[1] If the first response is a success we return success.
This ignores the state of the second answer and in fact
incorrectly sets errno and h_errno to that of the second
answer. However because the response is a success we ignore
*errnop and *h_errnop (though that means you touched errno on
success). We are being conservative here and returning the
likely IPv4 response in the first answer as a success.
[2] If the first response is a recoverable TRYAGAIN we return
that instead of looking at the second response. The
expectation here is that we have failed to get an IPv4 response
and should retry both queries.
[3] If the first response was not a SUCCESS and the second
response is not NOTFOUND (had a SUCCESS, need to TRYAGAIN,
or failed entirely e.g. TRYAGAIN' and UNAVAIL) then use the
result from the second response, otherwise the first responses
status is used. Again we have some odd side-effects when the
second response is NOTFOUND because we overwrite *errnop and
*h_errnop that means that a first answer of NOTFOUND might see
its *errnop and *h_errnop values altered. Whether it matters
in practice that a first response NOTFOUND has the wrong
*errnop and *h_errnop is undecided.
[4] If the first response is UNAVAIL we return that instead of
looking at the second response. The expectation here is that
it will have failed similarly e.g. configuration failure.
[5] Testing this code is complicated by the fact that truncated
second response buffers might be returned as SUCCESS if the
first answer is a SUCCESS. To fix this we add symmetry to
TRYAGAIN with the second response. If the second response
is a recoverable error we now return TRYAGIN even if the first
response was SUCCESS. */
if (anslen1 > 0)
status = gaih_getanswer_slice(answer1, anslen1, qname,
&pat, &buffer, &buflen,
errnop, h_errnop, ttlp,
&first);
if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND
|| (status == NSS_STATUS_TRYAGAIN
/* We want to look at the second answer in case of an
@@ -1242,8 +1343,15 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
&pat, &buffer, &buflen,
errnop, h_errnop, ttlp,
&first);
/* Use the second response status in some cases. */
if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND)
status = status2;
/* Do not return a truncated second response (unless it was
unavoidable e.g. unrecoverable TRYAGAIN). */
if (status == NSS_STATUS_SUCCESS
&& (status2 == NSS_STATUS_TRYAGAIN
&& *errnop == ERANGE && *h_errnop != NO_RECOVERY))
status = NSS_STATUS_TRYAGAIN;
}
return status;
+3
View File
@@ -396,6 +396,7 @@ __libc_res_nsearch(res_state statp,
{
free (*answerp2);
*answerp2 = NULL;
*nanswerp2 = 0;
*answerp2_malloced = 0;
}
}
@@ -447,6 +448,7 @@ __libc_res_nsearch(res_state statp,
{
free (*answerp2);
*answerp2 = NULL;
*nanswerp2 = 0;
*answerp2_malloced = 0;
}
@@ -521,6 +523,7 @@ __libc_res_nsearch(res_state statp,
{
free (*answerp2);
*answerp2 = NULL;
*nanswerp2 = 0;
*answerp2_malloced = 0;
}
if (saved_herrno != -1)
+197 -67
View File
@@ -1,3 +1,20 @@
/* Copyright (C) 2016 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/>. */
/*
* Copyright (c) 1985, 1989, 1993
* The Regents of the University of California. All rights reserved.
@@ -361,6 +378,8 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
#ifdef USE_HOOKS
if (__glibc_unlikely (statp->qhook || statp->rhook)) {
if (anssiz < MAXPACKET && ansp) {
/* Always allocate MAXPACKET, callers expect
this specific size. */
u_char *buf = malloc (MAXPACKET);
if (buf == NULL)
return (-1);
@@ -660,6 +679,77 @@ libresolv_hidden_def (res_nsend)
/* Private */
/* The send_vc function is responsible for sending a DNS query over TCP
to the nameserver numbered NS from the res_state STATP i.e.
EXT(statp).nssocks[ns]. The function supports sending both IPv4 and
IPv6 queries at the same serially on the same socket.
Please note that for TCP there is no way to disable sending both
queries, unlike UDP, which honours RES_SNGLKUP and RES_SNGLKUPREOP
and sends the queries serially and waits for the result after each
sent query. This implemetnation should be corrected to honour these
options.
Please also note that for TCP we send both queries over the same
socket one after another. This technically violates best practice
since the server is allowed to read the first query, respond, and
then close the socket (to service another client). If the server
does this, then the remaining second query in the socket data buffer
will cause the server to send the client an RST which will arrive
asynchronously and the client's OS will likely tear down the socket
receive buffer resulting in a potentially short read and lost
response data. This will force the client to retry the query again,
and this process may repeat until all servers and connection resets
are exhausted and then the query will fail. It's not known if this
happens with any frequency in real DNS server implementations. This
implementation should be corrected to use two sockets by default for
parallel queries.
The query stored in BUF of BUFLEN length is sent first followed by
the query stored in BUF2 of BUFLEN2 length. Queries are sent
serially on the same socket.
Answers to the query are stored firstly in *ANSP up to a max of
*ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
is non-NULL (to indicate that modifying the answer buffer is allowed)
then malloc is used to allocate a new response buffer and ANSCP and
ANSP will both point to the new buffer. If more than *ANSSIZP bytes
are needed but ANSCP is NULL, then as much of the response as
possible is read into the buffer, but the results will be truncated.
When truncation happens because of a small answer buffer the DNS
packets header field TC will bet set to 1, indicating a truncated
message and the rest of the socket data will be read and discarded.
Answers to the query are stored secondly in *ANSP2 up to a max of
*ANSSIZP2 bytes, with the actual response length stored in
*RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
is non-NULL (required for a second query) then malloc is used to
allocate a new response buffer, *ANSSIZP2 is set to the new buffer
size and *ANSP2_MALLOCED is set to 1.
The ANSP2_MALLOCED argument will eventually be removed as the
change in buffer pointer can be used to detect the buffer has
changed and that the caller should use free on the new buffer.
Note that the answers may arrive in any order from the server and
therefore the first and second answer buffers may not correspond to
the first and second queries.
It is not supported to call this function with a non-NULL ANSP2
but a NULL ANSCP. Put another way, you can call send_vc with a
single unmodifiable buffer or two modifiable buffers, but no other
combination is supported.
It is the caller's responsibility to free the malloc allocated
buffers by detecting that the pointers have changed from their
original values i.e. *ANSCP or *ANSP2 has changed.
If errors are encountered then *TERRNO is set to an appropriate
errno value and a zero result is returned for a recoverable error,
and a less-than zero result is returned for a non-recoverable error.
If no errors are encountered then *TERRNO is left unmodified and
a the length of the first response in bytes is returned. */
static int
send_vc(res_state statp,
const u_char *buf, int buflen, const u_char *buf2, int buflen2,
@@ -669,11 +759,7 @@ send_vc(res_state statp,
{
const HEADER *hp = (HEADER *) buf;
const HEADER *hp2 = (HEADER *) buf2;
u_char *ans = *ansp;
int orig_anssizp = *anssizp;
// XXX REMOVE
// int anssiz = *anssizp;
HEADER *anhp = (HEADER *) ans;
HEADER *anhp = (HEADER *) *ansp;
struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns];
int truncating, connreset, n;
/* On some architectures compiler might emit a warning indicating
@@ -766,6 +852,8 @@ send_vc(res_state statp,
* Receive length & response
*/
int recvresp1 = 0;
/* Skip the second response if there is no second query.
To do that we mark the second response as received. */
int recvresp2 = buf2 == NULL;
uint16_t rlen16;
read_len:
@@ -802,40 +890,14 @@ send_vc(res_state statp,
u_char **thisansp;
int *thisresplenp;
if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
/* We have not received any responses
yet or we only have one response to
receive. */
thisanssizp = anssizp;
thisansp = anscp ?: ansp;
assert (anscp != NULL || ansp2 == NULL);
thisresplenp = &resplen;
} else {
if (*anssizp != MAXPACKET) {
/* No buffer allocated for the first
reply. We can try to use the rest
of the user-provided buffer. */
#if __GNUC_PREREQ (4, 7)
DIAG_PUSH_NEEDS_COMMENT;
DIAG_IGNORE_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
#endif
#if _STRING_ARCH_unaligned
*anssizp2 = orig_anssizp - resplen;
*ansp2 = *ansp + resplen;
#else
int aligned_resplen
= ((resplen + __alignof__ (HEADER) - 1)
& ~(__alignof__ (HEADER) - 1));
*anssizp2 = orig_anssizp - aligned_resplen;
*ansp2 = *ansp + aligned_resplen;
#endif
#if __GNUC_PREREQ (4, 7)
DIAG_POP_NEEDS_COMMENT;
#endif
} else {
/* The first reply did not fit into the
user-provided buffer. Maybe the second
answer will. */
*anssizp2 = orig_anssizp;
*ansp2 = *ansp;
}
thisanssizp = anssizp2;
thisansp = ansp2;
thisresplenp = resplen2;
@@ -843,10 +905,14 @@ send_vc(res_state statp,
anhp = (HEADER *) *thisansp;
*thisresplenp = rlen;
if (rlen > *thisanssizp) {
/* Yes, we test ANSCP here. If we have two buffers
both will be allocatable. */
if (__glibc_likely (anscp != NULL)) {
/* Is the answer buffer too small? */
if (*thisanssizp < rlen) {
/* If the current buffer is not the the static
user-supplied buffer then we can reallocate
it. */
if (thisansp != NULL && thisansp != ansp) {
/* Always allocate MAXPACKET, callers expect
this specific size. */
u_char *newp = malloc (MAXPACKET);
if (newp == NULL) {
*terrno = ENOMEM;
@@ -858,6 +924,9 @@ send_vc(res_state statp,
if (thisansp == ansp2)
*ansp2_malloced = 1;
anhp = (HEADER *) newp;
/* A uint16_t can't be larger than MAXPACKET
thus it's safe to allocate MAXPACKET but
read RLEN bytes instead. */
len = rlen;
} else {
Dprint(statp->options & RES_DEBUG,
@@ -1021,6 +1090,66 @@ reopen (res_state statp, int *terrno, int ns)
return 1;
}
/* The send_dg function is responsible for sending a DNS query over UDP
to the nameserver numbered NS from the res_state STATP i.e.
EXT(statp).nssocks[ns]. The function supports IPv4 and IPv6 queries
along with the ability to send the query in parallel for both stacks
(default) or serially (RES_SINGLKUP). It also supports serial lookup
with a close and reopen of the socket used to talk to the server
(RES_SNGLKUPREOP) to work around broken name servers.
The query stored in BUF of BUFLEN length is sent first followed by
the query stored in BUF2 of BUFLEN2 length. Queries are sent
in parallel (default) or serially (RES_SINGLKUP or RES_SNGLKUPREOP).
Answers to the query are stored firstly in *ANSP up to a max of
*ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
is non-NULL (to indicate that modifying the answer buffer is allowed)
then malloc is used to allocate a new response buffer and ANSCP and
ANSP will both point to the new buffer. If more than *ANSSIZP bytes
are needed but ANSCP is NULL, then as much of the response as
possible is read into the buffer, but the results will be truncated.
When truncation happens because of a small answer buffer the DNS
packets header field TC will bet set to 1, indicating a truncated
message, while the rest of the UDP packet is discarded.
Answers to the query are stored secondly in *ANSP2 up to a max of
*ANSSIZP2 bytes, with the actual response length stored in
*RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
is non-NULL (required for a second query) then malloc is used to
allocate a new response buffer, *ANSSIZP2 is set to the new buffer
size and *ANSP2_MALLOCED is set to 1.
The ANSP2_MALLOCED argument will eventually be removed as the
change in buffer pointer can be used to detect the buffer has
changed and that the caller should use free on the new buffer.
Note that the answers may arrive in any order from the server and
therefore the first and second answer buffers may not correspond to
the first and second queries.
It is not supported to call this function with a non-NULL ANSP2
but a NULL ANSCP. Put another way, you can call send_vc with a
single unmodifiable buffer or two modifiable buffers, but no other
combination is supported.
It is the caller's responsibility to free the malloc allocated
buffers by detecting that the pointers have changed from their
original values i.e. *ANSCP or *ANSP2 has changed.
If an answer is truncated because of UDP datagram DNS limits then
*V_CIRCUIT is set to 1 and the return value non-zero to indicate to
the caller to retry with TCP. The value *GOTSOMEWHERE is set to 1
if any progress was made reading a response from the nameserver and
is used by the caller to distinguish between ECONNREFUSED and
ETIMEDOUT (the latter if *GOTSOMEWHERE is 1).
If errors are encountered then *TERRNO is set to an appropriate
errno value and a zero result is returned for a recoverable error,
and a less-than zero result is returned for a non-recoverable error.
If no errors are encountered then *TERRNO is left unmodified and
a the length of the first response in bytes is returned. */
static int
send_dg(res_state statp,
const u_char *buf, int buflen, const u_char *buf2, int buflen2,
@@ -1030,8 +1159,6 @@ send_dg(res_state statp,
{
const HEADER *hp = (HEADER *) buf;
const HEADER *hp2 = (HEADER *) buf2;
u_char *ans = *ansp;
int orig_anssizp = *anssizp;
struct timespec now, timeout, finish;
struct pollfd pfd[1];
int ptimeout;
@@ -1064,6 +1191,8 @@ send_dg(res_state statp,
int need_recompute = 0;
int nwritten = 0;
int recvresp1 = 0;
/* Skip the second response if there is no second query.
To do that we mark the second response as received. */
int recvresp2 = buf2 == NULL;
pfd[0].fd = EXT(statp).nssocks[ns];
pfd[0].events = POLLOUT;
@@ -1227,55 +1356,56 @@ send_dg(res_state statp,
int *thisresplenp;
if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
/* We have not received any responses
yet or we only have one response to
receive. */
thisanssizp = anssizp;
thisansp = anscp ?: ansp;
assert (anscp != NULL || ansp2 == NULL);
thisresplenp = &resplen;
} else {
if (*anssizp != MAXPACKET) {
/* No buffer allocated for the first
reply. We can try to use the rest
of the user-provided buffer. */
#if _STRING_ARCH_unaligned
*anssizp2 = orig_anssizp - resplen;
*ansp2 = *ansp + resplen;
#else
int aligned_resplen
= ((resplen + __alignof__ (HEADER) - 1)
& ~(__alignof__ (HEADER) - 1));
*anssizp2 = orig_anssizp - aligned_resplen;
*ansp2 = *ansp + aligned_resplen;
#endif
} else {
/* The first reply did not fit into the
user-provided buffer. Maybe the second
answer will. */
*anssizp2 = orig_anssizp;
*ansp2 = *ansp;
}
thisanssizp = anssizp2;
thisansp = ansp2;
thisresplenp = resplen2;
}
if (*thisanssizp < MAXPACKET
/* Yes, we test ANSCP here. If we have two buffers
both will be allocatable. */
&& anscp
/* If the current buffer is not the the static
user-supplied buffer then we can reallocate
it. */
&& (thisansp != NULL && thisansp != ansp)
#ifdef FIONREAD
/* Is the size too small? */
&& (ioctl (pfd[0].fd, FIONREAD, thisresplenp) < 0
|| *thisanssizp < *thisresplenp)
#endif
) {
/* Always allocate MAXPACKET, callers expect
this specific size. */
u_char *newp = malloc (MAXPACKET);
if (newp != NULL) {
*anssizp = MAXPACKET;
*thisansp = ans = newp;
*thisanssizp = MAXPACKET;
*thisansp = newp;
if (thisansp == ansp2)
*ansp2_malloced = 1;
}
}
/* We could end up with truncation if anscp was NULL
(not allowed to change caller's buffer) and the
response buffer size is too small. This isn't a
reliable way to detect truncation because the ioctl
may be an inaccurate report of the UDP message size.
Therefore we use this only to issue debug output.
To do truncation accurately with UDP we need
MSG_TRUNC which is only available on Linux. We
can abstract out the Linux-specific feature in the
future to detect truncation. */
if (__glibc_unlikely (*thisanssizp < *thisresplenp)) {
Dprint(statp->options & RES_DEBUG,
(stdout, ";; response may be truncated (UDP)\n")
);
}
HEADER *anhp = (HEADER *) *thisansp;
socklen_t fromlen = sizeof(struct sockaddr_in6);
assert (sizeof(from) <= fromlen);
+7 -5
View File
@@ -66,11 +66,11 @@ test-srcs := tst-fmtmsg
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 \
test-a64l tst-qsort tst-system testmb2 bug-strtod2 \
tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2 \
tst-makecontext tst-strtod4 tst-strtod5 tst-qsort2 \
tst-makecontext2 tst-strtod6 tst-unsetenv1 \
tst-limits tst-rand48 bug-strtod tst-setcontext \
tst-setcontext2 test-a64l tst-qsort tst-system testmb2 \
bug-strtod2 tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 \
tst-rand48-2 tst-makecontext tst-strtod4 tst-strtod5 \
tst-qsort2 tst-makecontext2 tst-strtod6 tst-unsetenv1 \
tst-makecontext3 bug-getcontext bug-fmtmsg1 \
tst-secure-getenv tst-strtod-overflow tst-strtod-round \
tst-tininess tst-strtod-underflow tst-tls-atexit
@@ -157,3 +157,5 @@ tst-tls-atexit-lib.so-no-z-defs = yes
$(objpfx)tst-tls-atexit: $(shared-thread-library) $(libdl)
$(objpfx)tst-tls-atexit.out: $(objpfx)tst-tls-atexit-lib.so
$(objpfx)tst-makecontext: $(libdl)
+13 -11
View File
@@ -269,18 +269,20 @@ unsetenv (name)
ep = __environ;
if (ep != NULL)
while (*ep != NULL)
if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
{
/* Found it. Remove this pointer by moving later ones back. */
char **dp = ep;
{
if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
{
/* Found it. Remove this pointer by moving later ones back. */
char **dp = ep;
do
dp[0] = dp[1];
while (*dp++);
/* Continue the loop in case NAME appears again. */
}
else
++ep;
do
dp[0] = dp[1];
while (*dp++);
/* Continue the loop in case NAME appears again. */
}
else
++ep;
}
UNLOCK;
+40 -1
View File
@@ -19,23 +19,62 @@
#include <stdlib.h>
#include <stdio.h>
#include <ucontext.h>
#include <assert.h>
#include <unwind.h>
#include <dlfcn.h>
#include <gnu/lib-names.h>
ucontext_t ucp;
char st1[8192];
char st1[16384];
__thread int thr;
int somevar = -76;
long othervar = -78L;
struct trace_arg
{
int cnt, size;
};
static _Unwind_Reason_Code
backtrace_helper (struct _Unwind_Context *ctx, void *a)
{
struct trace_arg *arg = a;
if (++arg->cnt == arg->size)
return _URC_END_OF_STACK;
return _URC_NO_REASON;
}
void
cf (int i)
{
struct trace_arg arg = { .size = 100, .cnt = -1 };
void *handle;
_Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *);
if (i != othervar || thr != 94)
{
printf ("i %d thr %d\n", i, thr);
exit (1);
}
/* Test if callback function of _Unwind_Backtrace is not called infinitely
times. See Bug 18508 or gcc bug "Bug 66303 - runtime.Caller() returns
infinitely deep stack frames on s390x.".
The go runtime calls backtrace_full() in
<gcc-src>/libbacktrace/backtrace.c, which uses _Unwind_Backtrace(). */
handle = dlopen (LIBGCC_S_SO, RTLD_LAZY);
if (handle != NULL)
{
unwind_backtrace = dlsym (handle, "_Unwind_Backtrace");
if (unwind_backtrace != NULL)
{
unwind_backtrace (backtrace_helper, &arg);
assert (arg.cnt != -1 && arg.cnt < 100);
}
dlclose (handle);
}
/* Since uc_link below has been set to NULL, setcontext is supposed to
terminate the process normally after this function returns. */
}
+230
View File
@@ -0,0 +1,230 @@
/* Testcase checks, if setcontext(), swapcontext() restores signal-mask
and if pending signals are delivered after those calls.
Copyright (C) 2015 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 <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <ucontext.h>
#include <unistd.h>
volatile int global;
volatile sig_atomic_t handlerCalled;
static void
check (const char *funcName)
{
sigset_t set;
/* check if SIGUSR2 is unblocked after setcontext-call. */
sigprocmask (SIG_BLOCK, NULL, &set);
if (sigismember (&set, SIGUSR2) != 0)
{
printf ("FAIL: SIGUSR2 is blocked after %s.\n", funcName);
exit (1);
}
if (sigismember (&set, SIGUSR1) != 1)
{
printf ("FAIL: SIGUSR1 is not blocked after %s.\n", funcName);
exit (1);
}
}
static void
signalmask (int how, int signum)
{
sigset_t set;
sigemptyset (&set);
sigaddset (&set, signum);
if (sigprocmask (how, &set, NULL) != 0)
{
printf ("FAIL: sigprocmaks (%d, %d, NULL): %m\n", how, signum);
exit (1);
}
}
static void
signalpending (int signum, const char *msg)
{
sigset_t set;
sigemptyset (&set);
if (sigpending (&set) != 0)
{
printf ("FAIL: sigpending: %m\n");
exit (1);
}
if (sigismember (&set, SIGUSR2) != 1)
{
printf ("FAIL: Signal %d is not pending %s\n", signum, msg);
exit (1);
}
}
static void
handler (int __attribute__ ((unused)) signum)
{
handlerCalled ++;
}
static int
do_test (void)
{
ucontext_t ctx, oldctx;
struct sigaction action;
pid_t pid;
pid = getpid ();
/* unblock SIGUSR2 */
signalmask (SIG_UNBLOCK, SIGUSR2);
/* block SIGUSR1 */
signalmask (SIG_BLOCK, SIGUSR1);
/* register handler for SIGUSR2 */
action.sa_flags = 0;
action.sa_handler = handler;
sigemptyset (&action.sa_mask);
sigaction (SIGUSR2, &action, NULL);
if (getcontext (&ctx) != 0)
{
printf ("FAIL: getcontext: %m\n");
exit (1);
}
global++;
if (global == 1)
{
puts ("after getcontext");
/* block SIGUSR2 */
signalmask (SIG_BLOCK, SIGUSR2);
/* send SIGUSR2 to me */
handlerCalled = 0;
kill (pid, SIGUSR2);
/* was SIGUSR2 handler called? */
if (handlerCalled != 0)
{
puts ("FAIL: signal handler was called, but signal was blocked.");
exit (1);
}
/* is SIGUSR2 pending? */
signalpending (SIGUSR2, "before setcontext");
/* SIGUSR2 will be unblocked by setcontext-call. */
if (setcontext (&ctx) != 0)
{
printf ("FAIL: setcontext: %m\n");
exit (1);
}
}
else if (global == 2)
{
puts ("after setcontext");
/* check SIGUSR1/2 */
check ("setcontext");
/* was SIGUSR2 handler called? */
if (handlerCalled != 1)
{
puts ("FAIL: signal handler was not called after setcontext.");
exit (1);
}
/* block SIGUSR2 */
signalmask (SIG_BLOCK, SIGUSR2);
/* send SIGUSR2 to me */
handlerCalled = 0;
kill (pid, SIGUSR2);
/* was SIGUSR2 handler called? */
if (handlerCalled != 0)
{
puts ("FAIL: signal handler was called, but signal was blocked.");
exit (1);
}
/* is SIGUSR2 pending? */
signalpending (SIGUSR2, "before swapcontext");
if (swapcontext (&oldctx, &ctx) != 0)
{
printf ("FAIL: swapcontext: %m\n");
exit (1);
}
puts ("after returned from swapcontext");
if (global != 3)
{
puts ("FAIL: returned from swapcontext without ctx-context called.");
exit (1);
}
puts ("test succeeded");
return 0;
}
else if ( global != 3 )
{
puts ("FAIL: 'global' not incremented three times");
exit (1);
}
puts ("after swapcontext");
/* check SIGUSR1/2 */
check ("swapcontext");
/* was SIGUSR2 handler called? */
if (handlerCalled != 1)
{
puts ("FAIL: signal handler was not called after swapcontext.");
exit (1);
}
/* check sigmask in old context of swapcontext-call */
if (sigismember (&oldctx.uc_sigmask, SIGUSR2) != 1)
{
puts ("FAIL: SIGUSR2 is not blocked in oldctx.uc_sigmask.");
exit (1);
}
if (sigismember (&oldctx.uc_sigmask, SIGUSR1) != 1)
{
puts ("FAIL: SIGUSR1 is not blocked in oldctx.uc_sigmaks.");
exit (1);
}
/* change to old context, which was gathered by swapcontext() call. */
setcontext (&oldctx);
puts ("FAIL: returned from setcontext (&oldctx)");
exit (1);
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
+2 -2
View File
@@ -36,8 +36,8 @@ ENTRY(__mempcpy_chk)
cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx)
jne 1f
call __init_cpu_features
leal __mempcpy_chk_ia32@GOTOFF(%ebx), %eax
1: testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx)
1: leal __mempcpy_chk_ia32@GOTOFF(%ebx), %eax
testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx)
jz 2f
leal __mempcpy_chk_sse2_unaligned@GOTOFF(%ebx), %eax
testl $bit_Fast_Unaligned_Load, FEATURE_OFFSET+index_Fast_Unaligned_Load+__cpu_features@GOTOFF(%ebx)
+1 -3
View File
@@ -82,9 +82,7 @@ typedef uintmax_t uatomic_max_t;
(__sync_synchronize (), __sync_lock_test_and_set (mem, value))
#define atomic_exchange_and_add(mem, value) \
({ __typeof (*mem) __result; \
__result = __sync_fetch_and_add ((mem), (int) (value)); \
__result; })
__sync_fetch_and_add ((mem), (value))
#define atomic_decrement_if_positive(mem) \
({ __typeof (*mem) __oldval, __val; \
+29
View File
@@ -19,6 +19,9 @@
# error "Never include <bits/link.h> directly; use <link.h> instead."
#endif
#if defined HAVE_S390_VX_ASM_SUPPORT
typedef char La_s390_vr[16];
#endif
#if __ELF_NATIVE_CLASS == 32
@@ -32,6 +35,16 @@ typedef struct La_s390_32_regs
uint32_t lr_r6;
double lr_fp0;
double lr_fp2;
# if defined HAVE_S390_VX_ASM_SUPPORT
La_s390_vr lr_v24;
La_s390_vr lr_v25;
La_s390_vr lr_v26;
La_s390_vr lr_v27;
La_s390_vr lr_v28;
La_s390_vr lr_v29;
La_s390_vr lr_v30;
La_s390_vr lr_v31;
# endif
} La_s390_32_regs;
/* Return values for calls from PLT on s390-32. */
@@ -40,6 +53,9 @@ typedef struct La_s390_32_retval
uint32_t lrv_r2;
uint32_t lrv_r3;
double lrv_fp0;
# if defined HAVE_S390_VX_ASM_SUPPORT
La_s390_vr lrv_v24;
# endif
} La_s390_32_retval;
@@ -77,6 +93,16 @@ typedef struct La_s390_64_regs
double lr_fp2;
double lr_fp4;
double lr_fp6;
# if defined HAVE_S390_VX_ASM_SUPPORT
La_s390_vr lr_v24;
La_s390_vr lr_v25;
La_s390_vr lr_v26;
La_s390_vr lr_v27;
La_s390_vr lr_v28;
La_s390_vr lr_v29;
La_s390_vr lr_v30;
La_s390_vr lr_v31;
# endif
} La_s390_64_regs;
/* Return values for calls from PLT on s390-64. */
@@ -84,6 +110,9 @@ typedef struct La_s390_64_retval
{
uint64_t lrv_r2;
double lrv_fp0;
# if defined HAVE_S390_VX_ASM_SUPPORT
La_s390_vr lrv_v24;
# endif
} La_s390_64_retval;
+41
View File
@@ -104,5 +104,46 @@ if test "$enable_lock_elision" = yes && test "$libc_cv_gcc_builtin_tbegin" = no
critic_missing="$critic_missing The used GCC has no support for __builtin_tbegin, which is needed for lock-elision on target S390."
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 vector instruction support" >&5
$as_echo_n "checking for S390 vector instruction support... " >&6; }
if ${libc_cv_asm_s390_vx+:} false; then :
$as_echo_n "(cached) " >&6
else
cat > conftest.c <<\EOF
void testvecinsn ()
{
__asm__ (".machine \"z13\" \n\t"
".machinemode \"zarch_nohighgprs\" \n\t"
"vistrbs %%v16,%%v17 \n\t"
"locghie %%r1,0" : :);
}
EOF
if { ac_try='${CC-cc} --shared conftest.c -o conftest.o &> /dev/null'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; } ;
then
libc_cv_asm_s390_vx=yes
else
libc_cv_asm_s390_vx=no
fi
rm -f conftest*
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_s390_vx" >&5
$as_echo "$libc_cv_asm_s390_vx" >&6; }
if test "$libc_cv_asm_s390_vx" = yes ;
then
$as_echo "#define HAVE_S390_VX_ASM_SUPPORT 1" >>confdefs.h
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Use binutils with vector-support in order to use optimized implementations." >&5
$as_echo "$as_me: WARNING: Use binutils with vector-support in order to use optimized implementations." >&2;}
fi
test -n "$critic_missing" && as_fn_error $? "
*** $critic_missing" "$LINENO" 5
+29
View File
@@ -36,5 +36,34 @@ if test "$enable_lock_elision" = yes && test "$libc_cv_gcc_builtin_tbegin" = no
critic_missing="$critic_missing The used GCC has no support for __builtin_tbegin, which is needed for lock-elision on target S390."
fi
AC_CACHE_CHECK(for S390 vector instruction support, libc_cv_asm_s390_vx, [dnl
cat > conftest.c <<\EOF
void testvecinsn ()
{
__asm__ (".machine \"z13\" \n\t"
".machinemode \"zarch_nohighgprs\" \n\t"
"vistrbs %%v16,%%v17 \n\t"
"locghie %%r1,0" : :);
}
EOF
dnl
dnl test, if assembler supports S390 vector instructions
if AC_TRY_COMMAND([${CC-cc} --shared conftest.c -o conftest.o &> /dev/null]) ;
then
libc_cv_asm_s390_vx=yes
else
libc_cv_asm_s390_vx=no
fi
rm -f conftest* ])
if test "$libc_cv_asm_s390_vx" = yes ;
then
AC_DEFINE(HAVE_S390_VX_ASM_SUPPORT)
else
AC_MSG_WARN([Use binutils with vector-support in order to use optimized implementations.])
fi
test -n "$critic_missing" && AC_MSG_ERROR([
*** $critic_missing])
+4 -4
View File
@@ -46,11 +46,11 @@
#if !defined PROCINFO_DECL && defined SHARED
._dl_s390_cap_flags
#else
PROCINFO_CLASS const char _dl_s390_cap_flags[11][9]
PROCINFO_CLASS const char _dl_s390_cap_flags[12][9]
#endif
#ifndef PROCINFO_DECL
= {
"esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh", "highgprs", "te"
"esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh", "highgprs", "te", "vx"
}
#endif
#if !defined SHARED || defined PROCINFO_DECL
@@ -62,11 +62,11 @@ PROCINFO_CLASS const char _dl_s390_cap_flags[11][9]
#if !defined PROCINFO_DECL && defined SHARED
._dl_s390_platforms
#else
PROCINFO_CLASS const char _dl_s390_platforms[7][7]
PROCINFO_CLASS const char _dl_s390_platforms[8][7]
#endif
#ifndef PROCINFO_DECL
= {
"g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12"
"g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13"
}
#endif
#if !defined SHARED || defined PROCINFO_DECL
+3 -2
View File
@@ -21,9 +21,9 @@
#define _DL_PROCINFO_H 1
#include <ldsodefs.h>
#define _DL_HWCAP_COUNT 10
#define _DL_HWCAP_COUNT 12
#define _DL_PLATFORMS_COUNT 5
#define _DL_PLATFORMS_COUNT 8
/* The kernel provides up to 32 capability bits with elf_hwcap. */
#define _DL_FIRST_PLATFORM 32
@@ -50,6 +50,7 @@ enum
HWCAP_S390_ETF3EH = 1 << 8,
HWCAP_S390_HIGH_GPRS = 1 << 9,
HWCAP_S390_TE = 1 << 10,
HWCAP_S390_VX = 1 << 11,
};
#define HWCAP_IMPORTANT (HWCAP_S390_ZARCH | HWCAP_S390_LDISP \
+24 -3
View File
@@ -89,6 +89,11 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
{
extern void _dl_runtime_resolve (Elf32_Word);
extern void _dl_runtime_profile (Elf32_Word);
#if defined HAVE_S390_VX_ASM_SUPPORT
extern void _dl_runtime_resolve_vx (Elf32_Word);
extern void _dl_runtime_profile_vx (Elf32_Word);
#endif
if (l->l_info[DT_JMPREL] && lazy)
{
@@ -116,7 +121,14 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
end in this function. */
if (__glibc_unlikely (profile))
{
#if defined HAVE_S390_VX_ASM_SUPPORT
if (GLRO(dl_hwcap) & HWCAP_S390_VX)
got[2] = (Elf32_Addr) &_dl_runtime_profile_vx;
else
got[2] = (Elf32_Addr) &_dl_runtime_profile;
#else
got[2] = (Elf32_Addr) &_dl_runtime_profile;
#endif
if (GLRO(dl_profile) != NULL
&& _dl_name_match_p (GLRO(dl_profile), l))
@@ -125,9 +137,18 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
GL(dl_profile_map) = l;
}
else
/* This function will get called to fix up the GOT entry indicated by
the offset on the stack, and then jump to the resolved address. */
got[2] = (Elf32_Addr) &_dl_runtime_resolve;
{
/* This function will get called to fix up the GOT entry indicated by
the offset on the stack, and then jump to the resolved address. */
#if defined HAVE_S390_VX_ASM_SUPPORT
if (GLRO(dl_hwcap) & HWCAP_S390_VX)
got[2] = (Elf32_Addr) &_dl_runtime_resolve_vx;
else
got[2] = (Elf32_Addr) &_dl_runtime_resolve;
#else
got[2] = (Elf32_Addr) &_dl_runtime_resolve;
#endif
}
}
return lazy;
+10 -122
View File
@@ -16,130 +16,18 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* This code is used in dl-runtime.c to call the `fixup' function
and then redirect to the address it returns. */
/* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile
* with the following linkage:
* r2 - r6 : parameter registers
* f0, f2 : floating point parameter registers
* 24(r15), 28(r15) : PLT arguments PLT1, PLT2
* 96(r15) : additional stack parameters
* The normal clobber rules for function calls apply:
* r0 - r5 : call clobbered
* r6 - r13 : call saved
* r14 : return address (call clobbered)
* r15 : stack pointer (call saved)
* f4, f6 : call saved
* f0 - f3, f5, f7 - f15 : call clobbered
*/
#include <sysdep.h>
.text
.globl _dl_runtime_resolve
.type _dl_runtime_resolve, @function
cfi_startproc
.align 16
_dl_runtime_resolve:
stm %r2,%r5,32(%r15) # save registers
st %r14,8(%r15)
cfi_offset (r14, -88)
lr %r0,%r15 # create stack frame
ahi %r15,-96
cfi_adjust_cfa_offset (96)
st 0,0(%r15)
lm %r2,%r3,120(%r15) # load args saved by PLT
basr %r1,0
0: l %r14,1f-0b(%r1)
bas %r14,0(%r14,%r1) # call resolver
lr %r1,%r2 # function addr returned in r2
ahi %r15,96 # remove stack frame
cfi_adjust_cfa_offset (-96)
l %r14,8(15) # restore registers
lm %r2,%r5,32(%r15)
br %r1
1: .long _dl_fixup - 0b
cfi_endproc
.size _dl_runtime_resolve, .-_dl_runtime_resolve
/* Create variant of _dl_runtime_resolve/profile for machines before z13.
No vector registers are saved/restored. */
#include <dl-trampoline.h>
#ifndef PROF
.globl _dl_runtime_profile
.type _dl_runtime_profile, @function
cfi_startproc
.align 16
_dl_runtime_profile:
stm %r2,%r6,32(%r15) # save registers
std %f0,56(%r15)
std %f2,64(%r15)
st %r6,8(%r15)
st %r12,12(%r15)
st %r14,16(%r15)
cfi_offset (r6, -64)
cfi_offset (f0, -40)
cfi_offset (f2, -32)
cfi_offset (r12, -84)
cfi_offset (r14, -80)
lr %r12,%r15 # create stack frame
cfi_def_cfa_register (12)
ahi %r15,-96
st %r12,0(%r15)
lm %r2,%r3,24(%r12) # load arguments saved by PLT
lr %r4,%r14 # return address as third parameter
basr %r1,0
0: l %r14,6f-0b(%r1)
la %r5,32(%r12) # pointer to struct La_s390_32_regs
la %r6,20(%r12) # long int * framesize
bas %r14,0(%r14,%r1) # call resolver
lr %r1,%r2 # function addr returned in r2
icm %r0,15,20(%r12) # load & test framesize
jnm 2f
lm %r2,%r6,32(%r12)
ld %f0,56(%r12)
ld %f2,64(%r12)
lr %r15,%r12 # remove stack frame
cfi_def_cfa_register (15)
l %r14,16(%r15) # restore registers
l %r12,12(%r15)
br %r1 # tail-call to the resolved function
cfi_def_cfa_register (12)
2: jz 4f # framesize == 0 ?
ahi %r0,7 # align framesize to 8
lhi %r2,-8
nr %r0,%r2
slr %r15,%r0 # make room for framesize bytes
st %r12,0(%r15)
la %r2,96(%r15)
la %r3,96(%r12)
srl %r0,3
3: mvc 0(8,%r2),0(%r3) # copy additional parameters
la %r2,8(%r2)
la %r3,8(%r3)
brct %r0,3b
4: lm %r2,%r6,32(%r12) # load register parameters
ld %f0,56(%r12)
ld %f2,64(%r12)
basr %r14,%r1 # call resolved function
stm %r2,%r3,72(%r12)
std %f0,80(%r12)
lm %r2,%r3,24(%r12) # load arguments saved by PLT
basr %r1,0
5: l %r14,7f-5b(%r1)
la %r4,32(%r12) # pointer to struct La_s390_32_regs
la %r5,72(%r12) # pointer to struct La_s390_32_retval
basr %r14,%r1 # call _dl_call_pltexit
lr %r15,%r12 # remove stack frame
cfi_def_cfa_register (15)
l %r14,16(%r15) # restore registers
l %r12,12(%r15)
br %r14
6: .long _dl_profile_fixup - 0b
7: .long _dl_call_pltexit - 5b
cfi_endproc
.size _dl_runtime_profile, .-_dl_runtime_profile
#if defined HAVE_S390_VX_ASM_SUPPORT
/* Create variant of _dl_runtime_resolve/profile for z13 and newer.
The vector registers are saved/restored, too.*/
# define _dl_runtime_resolve _dl_runtime_resolve_vx
# define _dl_runtime_profile _dl_runtime_profile_vx
# define RESTORE_VRS
# include <dl-trampoline.h>
#endif
+231
View File
@@ -0,0 +1,231 @@
/* PLT trampolines. s390 version.
Copyright (C) 2016 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* This code is used in dl-runtime.c to call the `fixup' function
and then redirect to the address it returns. */
/* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile
* with the following linkage:
* r2 - r6 : parameter registers
* f0, f2 : floating point parameter registers
* v24, v26, v28, v30, v25, v27, v29, v31 : vector parameter registers
* 24(r15), 28(r15) : PLT arguments PLT1, PLT2
* 96(r15) : additional stack parameters
* The normal clobber rules for function calls apply:
* r0 - r5 : call clobbered
* r6 - r13 : call saved
* r14 : return address (call clobbered)
* r15 : stack pointer (call saved)
* f4, f6 : call saved
* f0 - f3, f5, f7 - f15 : call clobbered
* v0 - v3, v5, v7 - v15 : bytes 0-7 overlap with fprs: call clobbered
bytes 8-15: call clobbered
* v4, v6 : bytes 0-7 overlap with f4, f6: call saved
bytes 8-15: call clobbered
* v16 - v31 : call clobbered
*/
.globl _dl_runtime_resolve
.type _dl_runtime_resolve, @function
cfi_startproc
.align 16
_dl_runtime_resolve:
stm %r2,%r5,32(%r15) # save registers
cfi_offset (r2, -64)
cfi_offset (r3, -60)
cfi_offset (r4, -56)
cfi_offset (r5, -52)
std %f0,56(%r15)
cfi_offset (f0, -40)
std %f2,64(%r15)
cfi_offset (f2, -32)
st %r14,8(%r15)
cfi_offset (r14, -88)
lr %r0,%r15
lm %r2,%r3,24(%r15) # load args saved by PLT
#ifdef RESTORE_VRS
ahi %r15,-224 # create stack frame
cfi_adjust_cfa_offset (224)
.machine push
.machine "z13"
.machinemode "zarch_nohighgprs"
vstm %v24,%v31,96(%r15) # store call-clobbered vr arguments
cfi_offset (v24, -224)
cfi_offset (v25, -208)
cfi_offset (v26, -192)
cfi_offset (v27, -176)
cfi_offset (v28, -160)
cfi_offset (v29, -144)
cfi_offset (v30, -128)
cfi_offset (v31, -112)
.machine pop
#else
ahi %r15,-96 # create stack frame
cfi_adjust_cfa_offset (96)
#endif
st %r0,0(%r15) # write backchain
basr %r1,0
0: l %r14,1f-0b(%r1)
bas %r14,0(%r14,%r1) # call _dl_fixup
lr %r1,%r2 # function addr returned in r2
#ifdef RESTORE_VRS
.machine push
.machine "z13"
.machinemode "zarch_nohighgprs"
vlm %v24,%v31,96(%r15) # restore vector registers
.machine pop
ahi %r15,224 # remove stack frame
cfi_adjust_cfa_offset (-224)
#else
ahi %r15,96 # remove stack frame
cfi_adjust_cfa_offset (-96)
#endif
l %r14,8(15) # restore registers
ld %f0,56(%r15)
ld %f2,64(%r15)
lm %r2,%r5,32(%r15)
br %r1
1: .long _dl_fixup - 0b
cfi_endproc
.size _dl_runtime_resolve, .-_dl_runtime_resolve
#ifndef PROF
.globl _dl_runtime_profile
.type _dl_runtime_profile, @function
cfi_startproc
.align 16
_dl_runtime_profile:
st %r12,12(%r15) # r12 is used as backup of r15
cfi_offset (r12, -84)
st %r14,16(%r15)
cfi_offset (r14, -80)
lr %r12,%r15 # backup stack pointer
cfi_def_cfa_register (12)
ahi %r15,-264 # create stack frame:
# 96 + sizeof(La_s390_32_regs)
st %r12,0(%r15) # save backchain
stm %r2,%r6,96(%r15) # save registers
cfi_offset (r2, -264) # + r6 needed as arg for
cfi_offset (r3, -260) # _dl_profile_fixup
cfi_offset (r4, -256)
cfi_offset (r5, -252)
cfi_offset (r6, -248)
std %f0,120(%r15)
cfi_offset (f0, -240)
std %f2,128(%r15)
cfi_offset (f2, -232)
#ifdef RESTORE_VRS
.machine push
.machine "z13"
.machinemode "zarch_nohighgprs"
vstm %v24,%v31,136(%r15) # store call-clobbered vr arguments
cfi_offset (v24, -224)
cfi_offset (v25, -208)
cfi_offset (v26, -192)
cfi_offset (v27, -176)
cfi_offset (v28, -160)
cfi_offset (v29, -144)
cfi_offset (v30, -128)
cfi_offset (v31, -112)
.machine pop
#endif
lm %r2,%r3,24(%r12) # load arguments saved by PLT
lr %r4,%r14 # return address as third parameter
basr %r1,0
0: l %r14,6f-0b(%r1)
la %r5,96(%r15) # pointer to struct La_s390_32_regs
la %r6,20(%r12) # long int * framesize
bas %r14,0(%r14,%r1) # call resolver
lr %r1,%r2 # function addr returned in r2
ld %f0,120(%r15) # restore call-clobbered arg fprs
ld %f2,128(%r15)
#ifdef RESTORE_VRS
.machine push
.machine "z13"
.machinemode "zarch_nohighgprs"
vlm %v24,%v31,136(%r15) # restore call-clobbered arg vrs
.machine pop
#endif
icm %r0,15,20(%r12) # load & test framesize
jnm 2f
lm %r2,%r6,96(%r15) # framesize < 0 means no pltexit call
# so we can do a tail call without
# copying the arg overflow area
lr %r15,%r12 # remove stack frame
cfi_def_cfa_register (15)
l %r14,16(%r15) # restore registers
l %r12,12(%r15)
br %r1 # tail-call to the resolved function
cfi_def_cfa_register (12)
2: la %r4,96(%r15) # pointer to struct La_s390_32_regs
st %r4,32(%r12)
jz 4f # framesize == 0 ?
ahi %r0,7 # align framesize to 8
lhi %r2,-8
nr %r0,%r2
slr %r15,%r0 # make room for framesize bytes
st %r12,0(%r15) # save backchain
la %r2,96(%r15)
la %r3,96(%r12)
srl %r0,3
3: mvc 0(8,%r2),0(%r3) # copy additional parameters
la %r2,8(%r2)
la %r3,8(%r3)
brct %r0,3b
4: lm %r2,%r6,0(%r4) # load register parameters
basr %r14,%r1 # call resolved function
stm %r2,%r3,40(%r12) # store return values r2, r3, f0
std %f0,48(%r12) # to struct La_s390_32_retval
#ifdef RESTORE_VRS
.machine push
.machine "z13"
vst %v24,56(%r12) # store return value v24
.machine pop
#endif
lm %r2,%r4,24(%r12) # r2, r3: load arguments saved by PLT
# r4: pointer to struct La_s390_32_regs
basr %r1,0
5: l %r14,7f-5b(%r1)
la %r5,40(%r12) # pointer to struct La_s390_32_retval
bas %r14,0(%r14,%r1) # call _dl_call_pltexit
lr %r15,%r12 # remove stack frame
cfi_def_cfa_register (15)
l %r14,16(%r15) # restore registers
l %r12,12(%r15)
lm %r2,%r3,40(%r15) # restore return values
ld %f0,48(%r15)
#ifdef RESTORE_VRS
.machine push
.machine "z13"
vl %v24,56(%r15) # restore return value v24
.machine pop
#endif
br %r14
6: .long _dl_profile_fixup - 0b
7: .long _dl_call_pltexit - 5b
cfi_endproc
.size _dl_runtime_profile, .-_dl_runtime_profile
#endif
+24 -3
View File
@@ -26,6 +26,7 @@
#include <sys/param.h>
#include <string.h>
#include <link.h>
#include <sysdeps/s390/dl-procinfo.h>
#include <dl-irel.h>
#define ELF_MACHINE_IRELATIVE R_390_IRELATIVE
@@ -78,6 +79,10 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
{
extern void _dl_runtime_resolve (Elf64_Word);
extern void _dl_runtime_profile (Elf64_Word);
#if defined HAVE_S390_VX_ASM_SUPPORT
extern void _dl_runtime_resolve_vx (Elf64_Word);
extern void _dl_runtime_profile_vx (Elf64_Word);
#endif
if (l->l_info[DT_JMPREL] && lazy)
{
@@ -105,7 +110,14 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
end in this function. */
if (__glibc_unlikely (profile))
{
#if defined HAVE_S390_VX_ASM_SUPPORT
if (GLRO(dl_hwcap) & HWCAP_S390_VX)
got[2] = (Elf64_Addr) &_dl_runtime_profile_vx;
else
got[2] = (Elf64_Addr) &_dl_runtime_profile;
#else
got[2] = (Elf64_Addr) &_dl_runtime_profile;
#endif
if (GLRO(dl_profile) != NULL
&& _dl_name_match_p (GLRO(dl_profile), l))
@@ -114,9 +126,18 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
GL(dl_profile_map) = l;
}
else
/* This function will get called to fix up the GOT entry indicated by
the offset on the stack, and then jump to the resolved address. */
got[2] = (Elf64_Addr) &_dl_runtime_resolve;
{
/* This function will get called to fix up the GOT entry indicated by
the offset on the stack, and then jump to the resolved address. */
#if defined HAVE_S390_VX_ASM_SUPPORT
if (GLRO(dl_hwcap) & HWCAP_S390_VX)
got[2] = (Elf64_Addr) &_dl_runtime_resolve_vx;
else
got[2] = (Elf64_Addr) &_dl_runtime_resolve;
#else
got[2] = (Elf64_Addr) &_dl_runtime_resolve;
#endif
}
}
return lazy;
+10 -118
View File
@@ -16,126 +16,18 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile
* with the following linkage:
* r2 - r6 : parameter registers
* f0, f2, f4, f6 : floating point parameter registers
* 48(r15), 56(r15) : PLT arguments PLT1, PLT2
* 160(r15) : additional stack parameters
* The normal clobber rules for function calls apply:
* r0 - r5 : call clobbered
* r6 - r13 : call saved
* r14 : return address (call clobbered)
* r15 : stack pointer (call saved)
* f1, f3, f5, f7 : call saved
* f0 - f3, f5, f7 - f15 : call clobbered
*/
#include <sysdep.h>
.text
.globl _dl_runtime_resolve
.type _dl_runtime_resolve, @function
cfi_startproc
.align 16
_dl_runtime_resolve:
stmg %r2,%r5,64(15) # save call-clobbered argument registers
stg %r14,96(15)
cfi_offset (r14, -64)
lgr %r0,%r15
aghi %r15,-160 # create stack frame
cfi_adjust_cfa_offset (160)
stg %r0,0(%r15) # write backchain
lmg %r2,%r3,208(%r15)# load args saved by PLT
brasl %r14,_dl_fixup # call fixup
lgr %r1,%r2 # function addr returned in r2
aghi %r15,160 # remove stack frame
cfi_adjust_cfa_offset (-160)
lg %r14,96(15) # restore registers
lmg %r2,%r5,64(15)
br %r1
cfi_endproc
.size _dl_runtime_resolve, .-_dl_runtime_resolve
/* Create variant of _dl_runtime_resolve/profile for machines before z13.
No vector registers are saved/restored. */
#include <dl-trampoline.h>
#ifndef PROF
.globl _dl_runtime_profile
.type _dl_runtime_profile, @function
cfi_startproc
.align 16
_dl_runtime_profile:
stmg %r2,%r6,64(%r15) # save call-clobbered arg regs
std %f0,104(%r15) # + r6 needed as arg for
std %f2,112(%r15) # _dl_profile_fixup
std %f4,120(%r15)
std %f6,128(%r15)
stg %r12,24(%r15) # r12 is used as backup of r15
stg %r14,32(%r15)
cfi_offset (r6, -96)
cfi_offset (f0, -56)
cfi_offset (f2, -48)
cfi_offset (f4, -40)
cfi_offset (f6, -32)
cfi_offset (r12, -136)
cfi_offset (r14, -128)
lgr %r12,%r15 # backup stack pointer
cfi_def_cfa_register (12)
aghi %r15,-160 # create stack frame
stg %r12,0(%r15) # save backchain
lmg %r2,%r3,48(%r12) # load arguments saved by PLT
lgr %r4,%r14 # return address as third parameter
la %r5,64(%r12) # pointer to struct La_s390_32_regs
la %r6,40(%r12) # long int * framesize
brasl %r14,_dl_profile_fixup # call resolver
lgr %r1,%r2 # function addr returned in r2
lg %r0,40(%r12) # load framesize
ltgr %r0,%r0
jnm 1f
lmg %r2,%r6,64(%r12) # framesize < 0 means no pltexit call
ld %f0,104(%r12) # so we can do a tail call without
ld %f2,112(%r12) # copying the arg overflow area
ld %f4,120(%r12)
ld %f6,128(%r12)
lgr %r15,%r12 # remove stack frame
cfi_def_cfa_register (15)
lg %r14,32(%r15) # restore registers
lg %r12,24(%r15)
br %r1 # tail-call to resolved function
cfi_def_cfa_register (12)
1: jz 4f # framesize == 0 ?
aghi %r0,7 # align framesize to 8
nill %r0,0xfff8
slgr %r15,%r0 # make room for framesize bytes
stg %r12,0(%r15)
la %r2,160(%r15)
la %r3,160(%r12)
srlg %r0,%r0,3
3: mvc 0(8,%r2),0(%r3) # copy additional parameters
la %r2,8(%r2)
la %r3,8(%r3)
brctg %r0,3b
4: lmg %r2,%r6,64(%r12) # load register parameters
ld %f0,104(%r12) # restore call-clobbered arg regs
ld %f2,112(%r12)
ld %f4,120(%r12)
ld %f6,128(%r12)
basr %r14,%r1 # call resolved function
stg %r2,136(%r12)
std %f0,144(%r12)
lmg %r2,%r3,48(%r12) # load arguments saved by PLT
la %r4,32(%r12) # pointer to struct La_s390_32_regs
la %r5,72(%r12) # pointer to struct La_s390_32_retval
brasl %r14,_dl_call_pltexit
lgr %r15,%r12 # remove stack frame
cfi_def_cfa_register (15)
lg %r14,32(%r15) # restore registers
lg %r12,24(%r15)
br %r14
cfi_endproc
.size _dl_runtime_profile, .-_dl_runtime_profile
#if defined HAVE_S390_VX_ASM_SUPPORT
/* Create variant of _dl_runtime_resolve/profile for z13 and newer.
The vector registers are saved/restored, too.*/
# define _dl_runtime_resolve _dl_runtime_resolve_vx
# define _dl_runtime_profile _dl_runtime_profile_vx
# define RESTORE_VRS
# include <dl-trampoline.h>
#endif
+225
View File
@@ -0,0 +1,225 @@
/* PLT trampolines. s390x version.
Copyright (C) 2016 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/>. */
/* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile
* with the following linkage:
* r2 - r6 : parameter registers
* f0, f2, f4, f6 : floating point parameter registers
* v24, v26, v28, v30, v25, v27, v29, v31 : vector parameter registers
* 48(r15), 56(r15) : PLT arguments PLT1, PLT2
* 160(r15) : additional stack parameters
* The normal clobber rules for function calls apply:
* r0 - r5 : call clobbered
* r6 - r13 : call saved
* r14 : return address (call clobbered)
* r15 : stack pointer (call saved)
* f0 - f7 : call clobbered
* f8 - f15 : call saved
* v0 - v7 : bytes 0-7 overlap with f0-f7: call clobbered
bytes 8-15: call clobbered
* v8 - v15 : bytes 0-7 overlap with f8-f15: call saved
bytes 8-15: call clobbered
* v16 - v31 : call clobbered
*/
.globl _dl_runtime_resolve
.type _dl_runtime_resolve, @function
cfi_startproc
.align 16
_dl_runtime_resolve:
stmg %r2,%r5,64(%r15) # save call-clobbered argument registers
cfi_offset (r2, -96)
cfi_offset (r3, -88)
cfi_offset (r4, -80)
cfi_offset (r5, -72)
std %f0,104(%r15)
cfi_offset (f0, -56)
std %f2,112(%r15)
cfi_offset (f2, -48)
std %f4,120(%r15)
cfi_offset (f4, -40)
std %f6,128(%r15)
cfi_offset (f6, -32)
stg %r14,96(15)
cfi_offset (r14, -64)
lmg %r2,%r3,48(%r15) # load args for fixup saved by PLT
lgr %r0,%r15
#ifdef RESTORE_VRS
aghi %r15,-288 # create stack frame
cfi_adjust_cfa_offset (288)
.machine push
.machine "z13"
vstm %v24,%v31,160(%r15)# store call-clobbered vector argument registers
cfi_offset (v24, -288)
cfi_offset (v25, -272)
cfi_offset (v26, -256)
cfi_offset (v27, -240)
cfi_offset (v28, -224)
cfi_offset (v29, -208)
cfi_offset (v30, -192)
cfi_offset (v31, -176)
.machine pop
#else
aghi %r15,-160 # create stack frame
cfi_adjust_cfa_offset (160)
#endif
stg %r0,0(%r15) # write backchain
brasl %r14,_dl_fixup # call _dl_fixup
lgr %r1,%r2 # function addr returned in r2
#ifdef RESTORE_VRS
.machine push
.machine "z13"
vlm %v24,%v31,160(%r15)# restore vector registers
.machine pop
aghi %r15,288 # remove stack frame
cfi_adjust_cfa_offset (-288)
#else
aghi %r15,160 # remove stack frame
cfi_adjust_cfa_offset (-160)
#endif
lg %r14,96(%r15) # restore registers
ld %f0,104(%r15)
ld %f2,112(%r15)
ld %f4,120(%r15)
ld %f6,128(%r15)
lmg %r2,%r5,64(%r15)
br %r1
cfi_endproc
.size _dl_runtime_resolve, .-_dl_runtime_resolve
#ifndef PROF
.globl _dl_runtime_profile
.type _dl_runtime_profile, @function
cfi_startproc
.align 16
_dl_runtime_profile:
stg %r12,24(%r15) # r12 is used as backup of r15
cfi_offset (r12, -136)
stg %r14,32(%r15)
cfi_offset (r14, -128)
lgr %r12,%r15 # backup stack pointer
cfi_def_cfa_register (12)
aghi %r15,-360 # create stack frame:
# 160 + sizeof(La_s390_64_regs)
stg %r12,0(%r15) # save backchain
stmg %r2,%r6,160(%r15) # save call-clobbered arg regs
cfi_offset (r2, -360) # + r6 needed as arg for
cfi_offset (r3, -352) # _dl_profile_fixup
cfi_offset (r4, -344)
cfi_offset (r5, -336)
cfi_offset (r6, -328)
std %f0,200(%r15)
cfi_offset (f0, -320)
std %f2,208(%r15)
cfi_offset (f2, -312)
std %f4,216(%r15)
cfi_offset (f4, -304)
std %f6,224(%r15)
cfi_offset (f6, -296)
#ifdef RESTORE_VRS
.machine push
.machine "z13"
vstm %v24,%v31,232(%r15) # store call-clobbered vector arguments
cfi_offset (v24, -288)
cfi_offset (v25, -272)
cfi_offset (v26, -256)
cfi_offset (v27, -240)
cfi_offset (v28, -224)
cfi_offset (v29, -208)
cfi_offset (v30, -192)
cfi_offset (v31, -176)
.machine pop
#endif
lmg %r2,%r3,48(%r12) # load arguments saved by PLT
lgr %r4,%r14 # return address as third parameter
la %r5,160(%r15) # pointer to struct La_s390_64_regs
la %r6,40(%r12) # long int * framesize
brasl %r14,_dl_profile_fixup # call resolver
lgr %r1,%r2 # function addr returned in r2
ld %f0,200(%r15) # restore call-clobbered arg fprs
ld %f2,208(%r15)
ld %f4,216(%r15)
ld %f6,224(%r15)
#ifdef RESTORE_VRS
.machine push
.machine "z13"
vlm %v24,%v31,232(%r15) # restore call-clobbered arg vrs
.machine pop
#endif
lg %r0,40(%r12) # load framesize
ltgr %r0,%r0
jnm 1f
lmg %r2,%r6,160(%r15) # framesize < 0 means no pltexit call
# so we can do a tail call without
# copying the arg overflow area
lgr %r15,%r12 # remove stack frame
cfi_def_cfa_register (15)
lg %r14,32(%r15) # restore registers
lg %r12,24(%r15)
br %r1 # tail-call to resolved function
cfi_def_cfa_register (12)
1: la %r4,160(%r15) # pointer to struct La_s390_64_regs
stg %r4,64(%r12)
jz 4f # framesize == 0 ?
aghi %r0,7 # align framesize to 8
nill %r0,0xfff8
slgr %r15,%r0 # make room for framesize bytes
stg %r12,0(%r15) # save backchain
la %r2,160(%r15)
la %r3,160(%r12)
srlg %r0,%r0,3
3: mvc 0(8,%r2),0(%r3) # copy additional parameters
la %r2,8(%r2) # depending on framesize
la %r3,8(%r3)
brctg %r0,3b
4: lmg %r2,%r6,0(%r4) # restore call-clobbered arg gprs
basr %r14,%r1 # call resolved function
stg %r2,72(%r12) # store return values r2, f0
std %f0,80(%r12) # to struct La_s390_64_retval
#ifdef RESTORE_VRS
.machine push
.machine "z13"
vst %v24,88(%r12) # store return value v24
.machine pop
#endif
lmg %r2,%r4,48(%r12) # r2, r3: load arguments saved by PLT
# r4: pointer to struct La_s390_64_regs
la %r5,72(%r12) # pointer to struct La_s390_64_retval
brasl %r14,_dl_call_pltexit
lgr %r15,%r12 # remove stack frame
cfi_def_cfa_register (15)
lg %r14,32(%r15) # restore registers
lg %r12,24(%r15)
lg %r2,72(%r15) # restore return values
ld %f0,80(%r15)
#ifdef RESTORE_VRS
.machine push
.machine "z13"
vl %v24,88(%r15) # restore return value v24
.machine pop
#endif
br %r14 # Jump back to caller
cfi_endproc
.size _dl_runtime_profile, .-_dl_runtime_profile
#endif
@@ -35,3 +35,4 @@
#define HWCAP_S390_ETF3EH 256
#define HWCAP_S390_HIGH_GPRS 512
#define HWCAP_S390_TE 1024
#define HWCAP_S390_VX 2048
@@ -17,6 +17,14 @@
#include <sysdep.h>
/* We do not want .eh_frame info so that __makecontext_ret stops unwinding
if backtrace was called within a context created by makecontext. (There
is also no .eh_frame info for _start or thread_start.) */
#undef cfi_startproc
#define cfi_startproc
#undef cfi_endproc
#define cfi_endproc
ENTRY(__makecontext_ret)
basr %r14,%r7
ltr %r8,%r8 /* Check whether uc_link is 0. */
@@ -34,7 +34,7 @@ ENTRY(__setcontext)
lr %r1,%r2
/* rt_sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL, sigsetsize). */
la %r2,SIG_BLOCK
la %r2,SIG_SETMASK
la %r3,SC_MASK(%r1)
slr %r4,%r4
lhi %r5,_NSIG8
@@ -24,7 +24,7 @@
/* __swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
Saves the machine context in oucp such that when it is activated,
it appears as if __swapcontextt() returned again, restores the
it appears as if __swapcontext() returned again, restores the
machine context in ucp and thereby resumes execution in that
context.
@@ -39,13 +39,6 @@ ENTRY(__swapcontext)
lr %r1,%r2
lr %r0,%r3
/* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask). */
la %r2,SIG_BLOCK
slr %r3,%r3
la %r4,SC_MASK(%r1)
lhi %r5,_NSIG8
svc SYS_ify(rt_sigprocmask)
/* Store fpu context. */
stfpc SC_FPC(%r1)
std %f0,SC_FPRS(%r1)
@@ -74,11 +67,12 @@ ENTRY(__swapcontext)
/* Store general purpose registers. */
stm %r0,%r15,SC_GPRS(%r1)
/* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */
la %r2,SIG_BLOCK
/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask,
sigsetsize). */
la %r2,SIG_SETMASK
lr %r5,%r0
la %r3,SC_MASK(%r5)
slr %r4,%r4
la %r4,SC_MASK(%r1)
lhi %r5,_NSIG8
svc SYS_ify(rt_sigprocmask)
@@ -17,6 +17,14 @@
#include <sysdep.h>
/* We do not want .eh_frame info so that __makecontext_ret stops unwinding
if backtrace was called within a context created by makecontext. (There
is also no .eh_frame info for _start or thread_start.) */
#undef cfi_startproc
#define cfi_startproc
#undef cfi_endproc
#define cfi_endproc
ENTRY(__makecontext_ret)
basr %r14,%r7
ltgr %r8,%r8 /* Check whether uc_link is 0. */
@@ -34,7 +34,7 @@ ENTRY(__setcontext)
lgr %r1,%r2
/* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */
la %r2,SIG_BLOCK
la %r2,SIG_SETMASK
la %r3,SC_MASK(%r1)
slgr %r4,%r4
lghi %r5,_NSIG8
@@ -24,7 +24,7 @@
/* __swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
Saves the machine context in oucp such that when it is activated,
it appears as if __swapcontextt() returned again, restores the
it appears as if __swapcontext() returned again, restores the
machine context in ucp and thereby resumes execution in that
context.
@@ -39,13 +39,6 @@ ENTRY(__swapcontext)
lgr %r1,%r2
lgr %r0,%r3
/* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask). */
la %r2,SIG_BLOCK
slgr %r3,%r3
la %r4,SC_MASK(%r1)
lghi %r5,_NSIG8
svc SYS_ify(rt_sigprocmask)
/* Store fpu context. */
stfpc SC_FPC(%r1)
std %f0,SC_FPRS(%r1)
@@ -74,12 +67,13 @@ ENTRY(__swapcontext)
/* Store general purpose registers. */
stmg %r0,%r15,SC_GPRS(%r1)
/* rt_sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL, sigsetsize). */
la %r2,SIG_BLOCK
/* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask,
sigsetsize). */
la %r2,SIG_SETMASK
lgr %r5,%r0
la %r3,SC_MASK(%r5)
la %r4,SC_MASK(%r1)
lghi %r5,_NSIG8
slgr %r4,%r4
svc SYS_ify(rt_sigprocmask)
/* Load fpu context. */
@@ -12,22 +12,3 @@ shmget - shmget i:iii __shmget shmget
semop - semop i:ipi __semop semop
semget - semget i:iii __semget semget
semctl - semctl i:iiii __semctl semctl
# proper socket implementations:
accept - accept Ci:iBN __libc_accept __accept accept
bind - bind i:ipi __bind bind
connect - connect Ci:ipi __libc_connect __connect connect
getpeername - getpeername i:ipp __getpeername getpeername
getsockname - getsockname i:ipp __getsockname getsockname
getsockopt - getsockopt i:iiiBN __getsockopt getsockopt
listen - listen i:ii __listen listen
recv - recv Ci:ibni __libc_recv __recv recv
recvfrom - recvfrom Ci:ibniBN __libc_recvfrom __recvfrom recvfrom
recvmsg - recvmsg Ci:ipi __libc_recvmsg __recvmsg recvmsg
send - send Ci:ibni __libc_send __send send
sendmsg - sendmsg Ci:ipi __libc_sendmsg __sendmsg sendmsg
sendto - sendto Ci:ibnibn __libc_sendto __sendto sendto
setsockopt - setsockopt i:iiibn __setsockopt setsockopt
shutdown - shutdown i:ii __shutdown shutdown
socket - socket i:iii __socket socket
socketpair - socketpair i:iiif __socketpair socketpair
@@ -20,6 +20,8 @@
# error "Never include <bits/sigaction.h> directly; use <signal.h> instead."
#endif
#include <bits/wordsize.h>
/* Structure describing the action to be taken when a signal arrives. */
struct sigaction
{
@@ -43,7 +45,9 @@ struct sigaction
__sigset_t sa_mask;
/* Special flags. */
#if __WORDSIZE == 64
int __glibc_reserved0;
#endif
int sa_flags;
/* Not used by Linux/Sparc yet. */
+2 -2
View File
@@ -117,7 +117,7 @@ rm -f conftest*
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_avx512" >&5
$as_echo "$libc_cv_asm_avx512" >&6; }
if test $libc_cv_asm_avx512 == yes; then
if test $libc_cv_asm_avx512 = yes; then
$as_echo "#define HAVE_AVX512_ASM_SUPPORT 1" >>confdefs.h
fi
@@ -244,7 +244,7 @@ rm -f conftest*
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_mpx" >&5
$as_echo "$libc_cv_asm_mpx" >&6; }
if test $libc_cv_asm_mpx == yes; then
if test $libc_cv_asm_mpx = yes; then
$as_echo "#define HAVE_MPX_SUPPORT 1" >>confdefs.h
fi
+2 -2
View File
@@ -34,7 +34,7 @@ else
libc_cv_asm_avx512=no
fi
rm -f conftest*])
if test $libc_cv_asm_avx512 == yes; then
if test $libc_cv_asm_avx512 = yes; then
AC_DEFINE(HAVE_AVX512_ASM_SUPPORT)
fi
@@ -86,7 +86,7 @@ else
libc_cv_asm_mpx=no
fi
rm -f conftest*])
if test $libc_cv_asm_mpx == yes; then
if test $libc_cv_asm_mpx = yes; then
AC_DEFINE(HAVE_MPX_SUPPORT)
fi
+13 -7
View File
@@ -510,13 +510,17 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
only a few elements. Dereference the pointers only if the format
requires this. Then it is ok to fail if the pointers are invalid. */
# define a_wkday \
((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \
? "?" : _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday)))
# define f_wkday \
((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \
? "?" : _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday)))
# define a_month \
((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \
? "?" : _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon)))
# define f_month \
((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \
? "?" : _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon)))
# define ampm \
((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
? NLW(PM_STR) : NLW(AM_STR)))
@@ -526,8 +530,10 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
# define ap_len STRLEN (ampm)
#else
# if !HAVE_STRFTIME
# define f_wkday (weekday_name[tp->tm_wday])
# define f_month (month_name[tp->tm_mon])
# define f_wkday (tp->tm_wday < 0 || tp->tm_wday > 6 \
? "?" : weekday_name[tp->tm_wday])
# define f_month (tp->tm_mon < 0 || tp->tm_mon > 11 \
? "?" : month_name[tp->tm_mon])
# define a_wkday f_wkday
# define a_month f_month
# define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11))
@@ -1321,7 +1327,7 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument
*tzset_called = true;
}
# endif
zone = tzname[tp->tm_isdst];
zone = tp->tm_isdst <= 1 ? tzname[tp->tm_isdst] : "?";
}
#endif
if (! zone)
+51 -1
View File
@@ -4,6 +4,56 @@
#include <time.h>
static int
do_bz18985 (void)
{
char buf[1000];
struct tm ttm;
int rc, ret = 0;
memset (&ttm, 1, sizeof (ttm));
ttm.tm_zone = NULL; /* Dereferenced directly if non-NULL. */
rc = strftime (buf, sizeof (buf), "%a %A %b %B %c %z %Z", &ttm);
if (rc == 66)
{
const char expected[]
= "? ? ? ? ? ? 16843009 16843009:16843009:16843009 16844909 +467836 ?";
if (0 != strcmp (buf, expected))
{
printf ("expected:\n %s\ngot:\n %s\n", expected, buf);
ret += 1;
}
}
else
{
printf ("expected 66, got %d\n", rc);
ret += 1;
}
/* Check negative values as well. */
memset (&ttm, 0xFF, sizeof (ttm));
ttm.tm_zone = NULL; /* Dereferenced directly if non-NULL. */
rc = strftime (buf, sizeof (buf), "%a %A %b %B %c %z %Z", &ttm);
if (rc == 30)
{
const char expected[] = "? ? ? ? ? ? -1 -1:-1:-1 1899 ";
if (0 != strcmp (buf, expected))
{
printf ("expected:\n %s\ngot:\n %s\n", expected, buf);
ret += 1;
}
}
else
{
printf ("expected 30, got %d\n", rc);
ret += 1;
}
return ret;
}
static struct
{
const char *fmt;
@@ -104,7 +154,7 @@ do_test (void)
}
}
return result;
return result + do_bz18985 ();
}
#define TEST_FUNCTION do_test ()