Compare commits

...
Author SHA1 Message Date
Zack Weinberg 98f5e8eb96 Avoid cancellable I/O primitives in ld.so.
Neither the <dlfcn.h> entry points, nor lazy symbol resolution, nor
initial shared library load-up, are cancellation points, so ld.so
should exclusively use I/O primitives that are not cancellable.  We
currently achieve this by having the cancellation hooks compile as
no-ops when IS_IN(rtld); this patch changes to using exclusively
_nocancel primitives in the source code instead, which makes the
intent clearer and significantly reduces the amount of code compiled
under IS_IN(rtld) as well as IS_IN(libc) -- in particular,
elf/Makefile no longer thinks we require a copy of unwind.c in
rtld-libc.a.  (The older mechanism is preserved as a backstop.)

The bulk of the change is splitting up the files that define the
_nocancel I/O functions, so they don't also define the variants that
*are* cancellation points; after which, the existing logic for picking
out the bits of libc that need to be recompiled as part of ld.so Just
Works.  I did this for all of the _nocancel functions, not just the
ones used by ld.so, for consistency.

fcntl was a little tricky because it's only a cancellation point for
certain opcodes (F_SETLKW(64), which can block), and the existing
__fcntl_nocancel wasn't applying the FCNTL_ADJUST_CMD hook, which
strikes me as asking for trouble, especially as the only nontrivial
definition of FCNTL_ADJUST_CMD (for powerpc64) changes F_*LK* opcodes.
To fix this, fcntl_common moves to fcntl_nocancel.c along with
__fcntl_nocancel, and changes its name to the extern (but hidden)
symbol __fcntl_nocancel_adjusted, so that regular fcntl can continue
calling it.  __fcntl_nocancel now applies FCNTL_ADJUST_CMD; so that
both both fcntl.c and fcntl_nocancel.c can see it, the only nontrivial
definition moves from sysdeps/u/s/l/powerpc/powerpc64/fcntl.c to
.../powerpc64/sysdep.h and becomes entirely a macro, instead of a macro
that calls an inline function.

The nptl version of libpthread also changes a little, because its
"compat-routines" formerly included files that defined all the
_nocancel functions it uses; instead of continuing to duplicate them,
I exported the relevant ones from libc.so as GLIBC_PRIVATE.  Since the
Linux fcntl.c calls a function defined by fcntl_nocancel.c, it can no
longer be used from libpthread.so; instead, introduce a custom
forwarder, pt-fcntl.c, and export __libc_fcntl from libc.so as
GLIBC_PRIVATE.  The nios2-linux ABI doesn't include a copy of vfork()
in libpthread, and it was handling that by manipulating
libpthread-routines in .../linux/nios2/Makefile; it is cleaner to do
what other such ports do, and have a pt-vfork.S that defines no symbols.

Right now, it appears that Hurd does not implement _nocancel I/O, so
sysdeps/generic/not-cancel.h will forward everything back to the
regular functions.  This changed the names of some of the functions
that sysdeps/mach/hurd/dl-sysdep.c needs to interpose.

	* elf/dl-load.c, elf/dl-misc.c, elf/dl-profile.c, elf/rtld.c
	* sysdeps/unix/sysv/linux/dl-sysdep.c
	Include not-cancel.h.  Use __close_nocancel instead of __close,
	__open64_nocancel instead of __open, __read_nocancel instead of
	__libc_read, and __write_nocancel instead of __libc_write.

	* csu/check_fds.c (check_one_fd)
	* sysdeps/posix/fdopendir.c (__fdopendir)
	* sysdeps/posix/opendir.c (__alloc_dir): Use __fcntl_nocancel
        instead of __fcntl and/or __libc_fcntl.

	* sysdeps/unix/sysv/linux/pthread_setname.c (pthread_setname_np)
	* sysdeps/unix/sysv/linux/pthread_getname.c (pthread_getname_np)
        * sysdeps/unix/sysv/linux/i386/smp.h (is_smp_system):
	Use __open64_nocancel instead of __open_nocancel.

	* sysdeps/unix/sysv/linux/not-cancel.h: Move all of the
	hidden_proto declarations to the end and issue them if either
	IS_IN(libc) or IS_IN(rtld).
	* sysdeps/unix/sysv/linux/Makefile [subdir=io] (sysdep_routines):
	Add close_nocancel, fcntl_nocancel, nanosleep_nocancel,
	open_nocancel, open64_nocancel, openat_nocancel, pause_nocancel,
	read_nocancel, waitpid_nocancel, write_nocancel.

        * io/Versions [GLIBC_PRIVATE]: Add __libc_fcntl,
        __fcntl_nocancel, __open64_nocancel, __write_nocancel.
        * posix/Versions: Add __nanosleep_nocancel, __pause_nocancel.

        * nptl/pt-fcntl.c: New file.
        * nptl/Makefile (pthread-compat-wrappers): Remove fcntl.
        (libpthread-routines): Add pt-fcntl.
        * include/fcntl.h (__fcntl_nocancel_adjusted): New function.
        (__libc_fcntl): Remove attribute_hidden.
	* sysdeps/unix/sysv/linux/fcntl.c (__libc_fcntl): Call
	__fcntl_nocancel_adjusted, not fcntl_common.
        (__fcntl_nocancel): Move to new file fcntl_nocancel.c.
	(fcntl_common): Rename to __fcntl_nocancel_adjusted; also move
	to fcntl_nocancel.c.
	* sysdeps/unix/sysv/linux/fcntl_nocancel.c: New file.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/fcntl.c: Remove file.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h:
	Define FCNTL_ADJUST_CMD here, as a self-contained macro.

	* sysdeps/unix/sysv/linux/close.c: Move __close_nocancel to...
	* sysdeps/unix/sysv/linux/close_nocancel.c: ...this new file.
	* sysdeps/unix/sysv/linux/nanosleep.c: Move __nanosleep_nocancel to...
	* sysdeps/unix/sysv/linux/nanosleep_nocancel.c: ...this new file.
	* sysdeps/unix/sysv/linux/open.c: Move __open_nocancel to...
	* sysdeps/unix/sysv/linux/open_nocancel.c: ...this new file.
	* sysdeps/unix/sysv/linux/open64.c: Move __open64_nocancel to...
	* sysdeps/unix/sysv/linux/open64_nocancel.c: ...this new file.
	* sysdeps/unix/sysv/linux/openat.c: Move __openat_nocancel to...
	* sysdeps/unix/sysv/linux/openat_nocancel.c: ...this new file.
	* sysdeps/unix/sysv/linux/openat64.c: Move __openat64_nocancel to...
	* sysdeps/unix/sysv/linux/openat64_nocancel.c: ...this new file.
	* sysdeps/unix/sysv/linux/pause.c: Move __pause_nocancel to...
	* sysdeps/unix/sysv/linux/pause_nocancel.c: ...this new file.
	* sysdeps/unix/sysv/linux/read.c: Move __read_nocancel to...
	* sysdeps/unix/sysv/linux/read_nocancel.c: ...this new file.
	* sysdeps/unix/sysv/linux/waitpid.c: Move __waitpid_nocancel to...
	* sysdeps/unix/sysv/linux/waitpid_nocancel.c: ...this new file.
	* sysdeps/unix/sysv/linux/write.c: Move __write_nocancel to...
	* sysdeps/unix/sysv/linux/write_nocancel.c: ...this new file.

        * sysdeps/unix/sysv/linux/nios2/Makefile: Don't override
        libpthread-routines.
        * sysdeps/unix/sysv/linux/nios2/pt-vfork.S: New file which
        defines nothing.

        * sysdeps/mach/hurd/dl-sysdep.c: Define __read instead of
        __libc_read, and __write instead of __libc_write.  Define
        __open64 in addition to __open.

(cherry picked from commit 329ea513b4)
2024-06-11 00:00:26 +00:00
Joseph Myers e00ff02338 Add narrowing divide functions.
This patch adds the narrowing divide functions from TS 18661-1 to
glibc's libm: fdiv, fdivl, ddivl, f32divf64, f32divf32x, f32xdivf64
for all configurations; f32divf64x, f32divf128, f64divf64x,
f64divf128, f32xdivf64x, f32xdivf128, f64xdivf128 for configurations
with _Float64x and _Float128; __nldbl_ddivl for ldbl-opt.

The changes are mostly essentially the same as for the other narrowing
functions, so the description of those generally applies to this patch
as well.

Tested for x86_64, x86, mips64 (all three ABIs, both hard and soft
float) and powerpc, and with build-many-glibcs.py.

	* math/Makefile (libm-narrow-fns): Add div.
	(libm-test-funcs-narrow): Likewise.
	* math/Versions (GLIBC_2.28): Add narrowing divide functions.
	* math/bits/mathcalls-narrow.h (div): Use __MATHCALL_NARROW.
	* math/gen-auto-libm-tests.c (test_functions): Add div.
	* math/math-narrow.h (CHECK_NARROW_DIV): New macro.
	(NARROW_DIV_ROUND_TO_ODD): Likewise.
	(NARROW_DIV_TRIVIAL): Likewise.
	* sysdeps/ieee754/float128/float128_private.h (__fdivl): New
	macro.
	(__ddivl): Likewise.
	* sysdeps/ieee754/ldbl-opt/Makefile (libnldbl-calls): Add fdiv and
	ddiv.
	(CFLAGS-nldbl-ddiv.c): New variable.
	(CFLAGS-nldbl-fdiv.c): Likewise.
	* sysdeps/ieee754/ldbl-opt/Versions (GLIBC_2.28): Add
	__nldbl_ddivl.
	* sysdeps/ieee754/ldbl-opt/nldbl-compat.h (__nldbl_ddivl): New
	prototype.
	* manual/arith.texi (Misc FP Arithmetic): Document fdiv, fdivl,
	ddivl, fMdivfN, fMdivfNx, fMxdivfN and fMxdivfNx.
	* math/auto-libm-test-in: Add tests of div.
	* math/auto-libm-test-out-narrow-div: New generated file.
	* math/libm-test-narrow-div.inc: New file.
	* sysdeps/i386/fpu/s_f32xdivf64.c: Likewise.
	* sysdeps/ieee754/dbl-64/s_f32xdivf64.c: Likewise.
	* sysdeps/ieee754/dbl-64/s_fdiv.c: Likewise.
	* sysdeps/ieee754/float128/s_f32divf128.c: Likewise.
	* sysdeps/ieee754/float128/s_f64divf128.c: Likewise.
	* sysdeps/ieee754/float128/s_f64xdivf128.c: Likewise.
	* sysdeps/ieee754/ldbl-128/s_ddivl.c: Likewise.
	* sysdeps/ieee754/ldbl-128/s_f64xdivf128.c: Likewise.
	* sysdeps/ieee754/ldbl-128/s_fdivl.c: Likewise.
	* sysdeps/ieee754/ldbl-128ibm/s_ddivl.c: Likewise.
	* sysdeps/ieee754/ldbl-128ibm/s_fdivl.c: Likewise.
	* sysdeps/ieee754/ldbl-96/s_ddivl.c: Likewise.
	* sysdeps/ieee754/ldbl-96/s_fdivl.c: Likewise.
	* sysdeps/ieee754/ldbl-opt/nldbl-ddiv.c: Likewise.
	* sysdeps/ieee754/ldbl-opt/nldbl-fdiv.c: Likewise.
	* sysdeps/ieee754/soft-fp/s_ddivl.c: Likewise.
	* sysdeps/ieee754/soft-fp/s_fdiv.c: Likewise.
	* sysdeps/ieee754/soft-fp/s_fdivl.c: Likewise.
	* sysdeps/powerpc/fpu/libm-test-ulps: Update.
	* sysdeps/mach/hurd/i386/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/aarch64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/alpha/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/arm/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/hppa/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/i386/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/ia64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/microblaze/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/nios2/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/riscv/rv64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sh/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist: Likewise.

(cherry picked from commit 632a6cbe44)
2024-06-10 23:50:46 +00:00
Joseph Myers 1ac71ef719 Add narrowing multiply functions.
This patch adds the narrowing multiply functions from TS 18661-1 to
glibc's libm: fmul, fmull, dmull, f32mulf64, f32mulf32x, f32xmulf64
for all configurations; f32mulf64x, f32mulf128, f64mulf64x,
f64mulf128, f32xmulf64x, f32xmulf128, f64xmulf128 for configurations
with _Float64x and _Float128; __nldbl_dmull for ldbl-opt.

The changes are mostly essentially the same as for the narrowing add
functions, so the description of those generally applies to this patch
as well.  f32xmulf64 for i386 cannot use precision control as used for
add and subtract, because that would result in double rounding for
subnormal results, so that uses round-to-odd with long double
intermediate result instead.  The soft-fp support involves adding a
new FP_TRUNC_COOKED since soft-fp multiplication uses cooked inputs
and outputs.

Tested for x86_64, x86, mips64 (all three ABIs, both hard and soft
float) and powerpc, and with build-many-glibcs.py.

	* math/Makefile (libm-narrow-fns): Add mul.
	(libm-test-funcs-narrow): Likewise.
	* math/Versions (GLIBC_2.28): Add narrowing multiply functions.
	* math/bits/mathcalls-narrow.h (mul): Use __MATHCALL_NARROW.
	* math/gen-auto-libm-tests.c (test_functions): Add mul.
	* math/math-narrow.h (CHECK_NARROW_MUL): New macro.
	(NARROW_MUL_ROUND_TO_ODD): Likewise.
	(NARROW_MUL_TRIVIAL): Likewise.
	* soft-fp/op-common.h (FP_TRUNC_COOKED): Likewise.
	* sysdeps/ieee754/float128/float128_private.h (__fmull): New
	macro.
	(__dmull): Likewise.
	* sysdeps/ieee754/ldbl-opt/Makefile (libnldbl-calls): Add fmul and
	dmul.
	(CFLAGS-nldbl-dmul.c): New variable.
	(CFLAGS-nldbl-fmul.c): Likewise.
	* sysdeps/ieee754/ldbl-opt/Versions (GLIBC_2.28): Add
	__nldbl_dmull.
	* sysdeps/ieee754/ldbl-opt/nldbl-compat.h (__nldbl_dmull): New
	prototype.
	* manual/arith.texi (Misc FP Arithmetic): Document fmul, fmull,
	dmull, fMmulfN, fMmulfNx, fMxmulfN and fMxmulfNx.
	* math/auto-libm-test-in: Add tests of mul.
	* math/auto-libm-test-out-narrow-mul: New generated file.
	* math/libm-test-narrow-mul.inc: New file.
	* sysdeps/i386/fpu/s_f32xmulf64.c: Likewise.
	* sysdeps/ieee754/dbl-64/s_f32xmulf64.c: Likewise.
	* sysdeps/ieee754/dbl-64/s_fmul.c: Likewise.
	* sysdeps/ieee754/float128/s_f32mulf128.c: Likewise.
	* sysdeps/ieee754/float128/s_f64mulf128.c: Likewise.
	* sysdeps/ieee754/float128/s_f64xmulf128.c: Likewise.
	* sysdeps/ieee754/ldbl-128/s_dmull.c: Likewise.
	* sysdeps/ieee754/ldbl-128/s_f64xmulf128.c: Likewise.
	* sysdeps/ieee754/ldbl-128/s_fmull.c: Likewise.
	* sysdeps/ieee754/ldbl-128ibm/s_dmull.c: Likewise.
	* sysdeps/ieee754/ldbl-128ibm/s_fmull.c: Likewise.
	* sysdeps/ieee754/ldbl-96/s_dmull.c: Likewise.
	* sysdeps/ieee754/ldbl-96/s_fmull.c: Likewise.
	* sysdeps/ieee754/ldbl-opt/nldbl-dmul.c: Likewise.
	* sysdeps/ieee754/ldbl-opt/nldbl-fmul.c: Likewise.
	* sysdeps/ieee754/soft-fp/s_dmull.c: Likewise.
	* sysdeps/ieee754/soft-fp/s_fmul.c: Likewise.
	* sysdeps/ieee754/soft-fp/s_fmull.c: Likewise.
	* sysdeps/powerpc/fpu/libm-test-ulps: Update.
	* sysdeps/mach/hurd/i386/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/aarch64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/alpha/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/arm/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/hppa/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/i386/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/ia64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/microblaze/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/nios2/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/riscv/rv64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sh/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist: Likewise.

(cherry picked from commit 69a01461ee)
2024-06-10 23:49:20 +00:00
Joseph Myers 07ea91c03b Add narrowing subtract functions.
This patch adds the narrowing subtract functions from TS 18661-1 to
glibc's libm: fsub, fsubl, dsubl, f32subf64, f32subf32x, f32xsubf64
for all configurations; f32subf64x, f32subf128, f64subf64x,
f64subf128, f32xsubf64x, f32xsubf128, f64xsubf128 for configurations
with _Float64x and _Float128; __nldbl_dsubl for ldbl-opt.

The changes are essentially the same as for the narrowing add
functions, so the description of those generally applies to this patch
as well.

Tested for x86_64, x86, mips64 (all three ABIs, both hard and soft
float) and powerpc, and with build-many-glibcs.py.

	* math/Makefile (libm-narrow-fns): Add sub.
	(libm-test-funcs-narrow): Likewise.
	* math/Versions (GLIBC_2.28): Add narrowing subtract functions.
	* math/bits/mathcalls-narrow.h (sub): Use __MATHCALL_NARROW.
	* math/gen-auto-libm-tests.c (test_functions): Add sub.
	* math/math-narrow.h (CHECK_NARROW_SUB): New macro.
	(NARROW_SUB_ROUND_TO_ODD): Likewise.
	(NARROW_SUB_TRIVIAL): Likewise.
	* sysdeps/ieee754/float128/float128_private.h (__fsubl): New
	macro.
	(__dsubl): Likewise.
	* sysdeps/ieee754/ldbl-opt/Makefile (libnldbl-calls): Add fsub and
	dsub.
	(CFLAGS-nldbl-dsub.c): New variable.
	(CFLAGS-nldbl-fsub.c): Likewise.
	* sysdeps/ieee754/ldbl-opt/Versions (GLIBC_2.28): Add
	__nldbl_dsubl.
	* sysdeps/ieee754/ldbl-opt/nldbl-compat.h (__nldbl_dsubl): New
	prototype.
	* manual/arith.texi (Misc FP Arithmetic): Document fsub, fsubl,
	dsubl, fMsubfN, fMsubfNx, fMxsubfN and fMxsubfNx.
	* math/auto-libm-test-in: Add tests of sub.
	* math/auto-libm-test-out-narrow-sub: New generated file.
	* math/libm-test-narrow-sub.inc: New file.
	* sysdeps/i386/fpu/s_f32xsubf64.c: Likewise.
	* sysdeps/ieee754/dbl-64/s_f32xsubf64.c: Likewise.
	* sysdeps/ieee754/dbl-64/s_fsub.c: Likewise.
	* sysdeps/ieee754/float128/s_f32subf128.c: Likewise.
	* sysdeps/ieee754/float128/s_f64subf128.c: Likewise.
	* sysdeps/ieee754/float128/s_f64xsubf128.c: Likewise.
	* sysdeps/ieee754/ldbl-128/s_dsubl.c: Likewise.
	* sysdeps/ieee754/ldbl-128/s_f64xsubf128.c: Likewise.
	* sysdeps/ieee754/ldbl-128/s_fsubl.c: Likewise.
	* sysdeps/ieee754/ldbl-128ibm/s_dsubl.c: Likewise.
	* sysdeps/ieee754/ldbl-128ibm/s_fsubl.c: Likewise.
	* sysdeps/ieee754/ldbl-96/s_dsubl.c: Likewise.
	* sysdeps/ieee754/ldbl-96/s_fsubl.c: Likewise.
	* sysdeps/ieee754/ldbl-opt/nldbl-dsub.c: Likewise.
	* sysdeps/ieee754/ldbl-opt/nldbl-fsub.c: Likewise.
	* sysdeps/ieee754/soft-fp/s_dsubl.c: Likewise.
	* sysdeps/ieee754/soft-fp/s_fsub.c: Likewise.
	* sysdeps/ieee754/soft-fp/s_fsubl.c: Likewise.
	* sysdeps/powerpc/fpu/libm-test-ulps: Update.
	* sysdeps/mach/hurd/i386/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/aarch64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/alpha/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/arm/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/hppa/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/i386/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/ia64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/microblaze/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/nios2/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/riscv/rv64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sh/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/tile/tilegx32/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/tile/tilegx64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist: Likewise.

(cherry picked from commit 8d3f9e85cf)
2024-06-10 23:47:49 +00:00
Joseph Myers 6683e677bc Add narrowing add functions.
This patch adds the narrowing add functions from TS 18661-1 to glibc's
libm: fadd, faddl, daddl, f32addf64, f32addf32x, f32xaddf64 for all
configurations; f32addf64x, f32addf128, f64addf64x, f64addf128,
f32xaddf64x, f32xaddf128, f64xaddf128 for configurations with
_Float64x and _Float128; __nldbl_daddl for ldbl-opt.  As discussed for
the build infrastructure patch, tgmath.h support is deliberately
deferred, and FP_FAST_* macros are not applicable without optimized
function implementations.

Function implementations are added for all relevant pairs of formats
(including certain cases of a format and itself where more than one
type has that format).  The main implementations use round-to-odd, or
a trivial computation in the case where both formats are the same or
where the wider format is IBM long double (in which case we don't
attempt to be correctly rounding).  The sysdeps/ieee754/soft-fp
implementations use soft-fp, and are used automatically for
configurations without exceptions and rounding modes by virtue of
existing Implies files.  As previously discussed, optimized versions
for particular architectures are possible, but not included.

i386 gets a special version of f32xaddf64 to avoid problems with
double rounding (similar to the existing fdim version), since this
function must round just once without an intermediate rounding to long
double.  (No such special version is needed for any other function,
because the nontrivial functions use round-to-odd, which does the
intermediate computation with the rounding mode set to round-to-zero,
and double rounding is OK except in round-to-nearest mode, so is OK
for that intermediate round-to-zero computation.)  mul and div will
need slightly different special versions for i386 (using round-to-odd
on long double instead of precision control) because of the
possibility of inexact intermediate results in the subnormal range for
double.

To reduce duplication among the different function implementations,
math-narrow.h gets macros CHECK_NARROW_ADD, NARROW_ADD_ROUND_TO_ODD
and NARROW_ADD_TRIVIAL.

In the trivial cases and for any architecture-specific optimized
implementations, the overhead of the errno setting might be
significant, but I think that's best handled through compiler built-in
functions rather than providing separate no-errno versions in glibc
(and likewise there are no __*_finite entry points for these function
provided, __*_finite effectively being no-errno versions at present in
most cases).

Tested for x86_64 and x86, with both GCC 6 and GCC 7.  Tested for
mips64 (all three ABIs, both hard and soft float) and powerpc with GCC
7.  Tested with build-many-glibcs.py with both GCC 6 and GCC 7.

	* math/Makefile (libm-narrow-fns): Add add.
	(libm-test-funcs-narrow): Likewise.
	* math/Versions (GLIBC_2.28): Add narrowing add functions.
	* math/bits/mathcalls-narrow.h (add): Use __MATHCALL_NARROW .
	* math/gen-auto-libm-tests.c (test_functions): Add add.
	* math/math-narrow.h (CHECK_NARROW_ADD): New macro.
	(NARROW_ADD_ROUND_TO_ODD): Likewise.
	(NARROW_ADD_TRIVIAL): Likewise.
	* sysdeps/ieee754/float128/float128_private.h (__faddl): New
	macro.
	(__daddl): Likewise.
	* sysdeps/ieee754/ldbl-opt/Makefile (libnldbl-calls): Add fadd and
	dadd.
	(CFLAGS-nldbl-dadd.c): New variable.
	(CFLAGS-nldbl-fadd.c): Likewise.
	* sysdeps/ieee754/ldbl-opt/Versions (GLIBC_2.28): Add
	__nldbl_daddl.
	* sysdeps/ieee754/ldbl-opt/nldbl-compat.h (__nldbl_daddl): New
	prototype.
	* manual/arith.texi (Misc FP Arithmetic): Document fadd, faddl,
	daddl, fMaddfN, fMaddfNx, fMxaddfN and fMxaddfNx.
	* math/auto-libm-test-in: Add tests of add.
	* math/auto-libm-test-out-narrow-add: New generated file.
	* math/libm-test-narrow-add.inc: New file.
	* sysdeps/i386/fpu/s_f32xaddf64.c: Likewise.
	* sysdeps/ieee754/dbl-64/s_f32xaddf64.c: Likewise.
	* sysdeps/ieee754/dbl-64/s_fadd.c: Likewise.
	* sysdeps/ieee754/float128/s_f32addf128.c: Likewise.
	* sysdeps/ieee754/float128/s_f64addf128.c: Likewise.
	* sysdeps/ieee754/float128/s_f64xaddf128.c: Likewise.
	* sysdeps/ieee754/ldbl-128/s_daddl.c: Likewise.
	* sysdeps/ieee754/ldbl-128/s_f64xaddf128.c: Likewise.
	* sysdeps/ieee754/ldbl-128/s_faddl.c: Likewise.
	* sysdeps/ieee754/ldbl-128ibm/s_daddl.c: Likewise.
	* sysdeps/ieee754/ldbl-128ibm/s_faddl.c: Likewise.
	* sysdeps/ieee754/ldbl-96/s_daddl.c: Likewise.
	* sysdeps/ieee754/ldbl-96/s_faddl.c: Likewise.
	* sysdeps/ieee754/ldbl-opt/nldbl-dadd.c: Likewise.
	* sysdeps/ieee754/ldbl-opt/nldbl-fadd.c: Likewise.
	* sysdeps/ieee754/soft-fp/s_daddl.c: Likewise.
	* sysdeps/ieee754/soft-fp/s_fadd.c: Likewise.
	* sysdeps/ieee754/soft-fp/s_faddl.c: Likewise.
	* sysdeps/powerpc/fpu/libm-test-ulps: Update.
	* sysdeps/mach/hurd/i386/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/aarch64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/alpha/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/arm/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/hppa/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/i386/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/ia64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/microblaze/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/nios2/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/riscv/rv64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sh/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/tile/tilegx32/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/tile/tilegx64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/64/libm.abilist: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist: Likewise.

(cherry picked from commit d8742dd82f)
2024-06-10 23:45:46 +00:00
Joseph Myers a0ee7ab46c Add build infrastructure for narrowing libm functions.
TS 18661-1 defines libm functions that carry out an operation (+ - * /
sqrt fma) on their arguments and return a result rounded to a
(usually) narrower type, as if the original result were computed to
infinite precision and then rounded directly to the result type
without any intermediate rounding to the argument type.  For example,
fadd, faddl and daddl for addition.  These are the last remaining TS
18661-1 functions left to be added to glibc.  TS 18661-3 extends this
to corresponding functions for _FloatN and _FloatNx types.

As functions parametrized by two rather than one varying
floating-point types, these functions require infrastructure in glibc
that was not required for previous libm functions.  This patch
provides such infrastructure - excluding test support, and actual
function implementations, which will be in subsequent patches.

Declaring the functions uses a header bits/mathcalls-narrow.h, which
is included many times, for each relevant pair of types.  This will
end up containing macro calls of the form

__MATHCALL_NARROW (__MATHCALL_NAME (add), __MATHCALL_REDIR_NAME (add), 2);

for each family of narrowing functions.  (The structure of this macro
call, with the calls to __MATHCALL_NAME and __MATHCALL_REDIR_NAME
there rather than in the definition of __MATHCALL_NARROW, arises from
the names such as "add" *not* themselves being reserved identifiers -
meaning it's necessary to avoid any indirection that would result in a
user-defined "add" macro being expanded.)  Whereas for existing
functions declaring long double functions is disabled if _LIBC in the
case where they alias double functions, to facilitate defining the
long double functions as aliases of the double ones, there is no such
logic for the narrowing functions in this patch.  Rather, the files
defining such functions are expected to use #define to hide the
original declarations of the alias names, to avoid errors about
defining aliases with incompatible types.

math/Makefile support is added for building the functions (listed in
libm-narrow-fns, currently empty) for all relevant pairs of types.  An
internal header math-narrow.h is added for macros shared between
multiple function implementations - currently a ROUND_TO_ODD macro to
facilitate writing functions using the round-to-odd implementation
approach, and alias macros to create all the required function
aliases.  libc_feholdexcept_setroundf128 and libc_feupdateenv_testf128
are added for use when required (only for x86_64).  float128_private.h
support is added for ldbl-128 narrowing functions to be used for
_Float128.

Certain things are specifically omitted from this patch and the
immediate followups.  tgmath.h support is deferred; there remain
unresolved questions about how the type-generic macros for these
functions are supposed to work, especially in the case of arguments of
integer type.  The math.h / bits/mathcalls-narrow.h logic, and the
logic for determining what functions / aliases to define, will need
some adjustments to support the sqrt and fma functions, where
e.g. f32xsqrtf64 can just be an alias for sqrt rather than a separate
function.  TS 18661-1 defines FP_FAST_* macros but no support is
included for defining them (they won't in general be true without
architecture-specific optimized function versions).

For each of the function groups (add sub mul div sqrt fma) there are
always six functions present (e.g. fadd, faddl, daddl, f32addf64,
f32addf32x, f32xaddf64).  When _Float64x and _Float128 are supported,
there are seven more (e.g. f32addf64x, f32addf128, f64addf64x,
f64addf128, f32xaddf64x, f32xaddf128, f64xaddf128).  In addition, in
the ldbl-opt case there are function names such as __nldbl_daddl (an
alias for f32xaddf64, which is not a reserved name in TS 18661-1, only
in TS 18661-3), for calls to daddl to be mapped to in the
-mlong-double-64 case.  (Calls to faddl just get mapped to fadd, and
for sqrt and fma there won't be __nldbl_* functions because dsqrtl and
dfmal can just be mapped to sqrt and fma with -mlong-double-64.)

While there are six or thirteen functions present in each group (plus
__nldbl_* names only as an ABI, not an API), not all are distinct;
they fall in various groups of aliases.  There are two distinct
versions built if long double has the same format as double; four if
they have distinct formats but there is no _Float64x or _Float128
support; five if long double has binary128 format; seven when
_Float128 is distinct from long double.

Architecture-specific optimized versions are possible, but not
included in my patches.  For example, IA64 generally supports
narrowing the result of most floating-point instructions; Power ISA
2.07 (POWER8) supports double values as arguments to float
instructions, with the results narrowed as expected; Power ISA 3
(POWER9) supports round-to-odd for float128 instructions, so meaning
that approach can be used without needing to set and restore the
rounding mode and test "inexact".  I intend to leave any such
optimized versions to the architecture maintainers.  Generally in such
cases it would also make sense for calls to these functions to be
expanded inline (given -fno-math-errno); I put a suggestion for TS
18661-1 built-in functions at <https://gcc.gnu.org/wiki/SummerOfCode>.

Tested for x86_64 (this patch in isolation, as well as testing for
various configurations in conjunction with further patches).

	* math/bits/mathcalls-narrow.h: New file.
	* include/bits/mathcalls-narrow.h: Likewise.
	* math/math-narrow.h: Likewise.
	* math/math.h (__MATHCALL_NARROW_ARGS_1): New macro.
	(__MATHCALL_NARROW_ARGS_2): Likewise.
	(__MATHCALL_NARROW_ARGS_3): Likewise.
	(__MATHCALL_NARROW_NORMAL): Likewise.
	(__MATHCALL_NARROW_REDIR): Likewise.
	(__MATHCALL_NARROW): Likewise.
	[__GLIBC_USE (IEC_60559_BFP_EXT)]: Repeatedly include
	<bits/mathcalls-narrow.h> with _Mret_, _Marg_ and __MATHCALL_NAME
	defined.
	[__GLIBC_USE (IEC_60559_TYPES_EXT)]: Likewise.
	* math/Makefile (headers): Add bits/mathcalls-narrow.h.
	(libm-narrow-fns): New variable.
	(libm-narrow-types-basic): Likewise.
	(libm-narrow-types-ldouble-yes): Likewise.
	(libm-narrow-types-float128-yes): Likewise.
	(libm-narrow-types-float128-alias-yes): Likewise.
	(libm-narrow-types): Likewise.
	(libm-routines): Add narrowing functions.
	* sysdeps/i386/fpu/fenv_private.h [__x86_64__]
	(libc_feholdexcept_setroundf128): New macro.
	[__x86_64__] (libc_feupdateenv_testf128): Likewise.
	* sysdeps/ieee754/float128/float128_private.h: Include
	<math/math-narrow.h>.
	[libc_feholdexcept_setroundf128] (libc_feholdexcept_setroundl):
	Undefine and redefine.
	[libc_feupdateenv_testf128] (libc_feupdateenv_testl): Likewise.
	(libm_alias_float_ldouble): Undefine and redefine.
	(libm_alias_double_ldouble): Likewise.

Signed-off-by: Pranav Kant <prka@google.com>
2024-06-10 23:44:25 +00:00
Siddhesh Poyarekar 82dcfc6d7b getaddrinfo: Fix leak with AI_ALL [BZ #28852]
Use realloc in convert_hostent_to_gaih_addrtuple and fix up pointers in
the result list so that a single block is maintained for
hostbyname3_r/hostbyname2_r and freed in gaih_inet.  This result is
never merged with any other results, since the hosts database does not
permit merging.

Resolves BZ #28852.

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: DJ Delorie <dj@redhat.com>
2024-02-02 00:46:11 +00:00
Justin King be3c0fe888 Optimize pthread_cond_timedwait to avoid unnecessary call to clock_gettime for CLOCK_MONOTONIC 2024-01-12 23:20:06 +00:00
Siddhesh Poyarekar 5643a977d0 getcwd: Set errno to ERANGE for size == 1 (CVE-2021-3999)
Cherry-picked from 23e0e8f5f1 in main branch.
Test included with this commit is not cherry-picked because it requires more
changes.

No valid path returned by getcwd would fit into 1 byte, so reject the
size early and return NULL with errno set to ERANGE.  This change is
prompted by CVE-2021-3999, which describes a single byte buffer
underflow and overflow when all of the following conditions are met:

- The buffer size (i.e. the second argument of getcwd) is 1 byte
- The current working directory is too long
- '/' is also mounted on the current working directory

Sequence of events:

- In sysdeps/unix/sysv/linux/getcwd.c, the syscall returns ENAMETOOLONG
  because the linux kernel checks for name length before it checks
  buffer size

- The code falls back to the generic getcwd in sysdeps/posix

- In the generic func, the buf[0] is set to '\0' on line 250

- this while loop on line 262 is bypassed:

    while (!(thisdev == rootdev && thisino == rootino))

  since the rootfs (/) is bind mounted onto the directory and the flow
  goes on to line 449, where it puts a '/' in the byte before the
  buffer.

- Finally on line 458, it moves 2 bytes (the underflowed byte and the
  '\0') to the buf[0] and buf[1], resulting in a 1 byte buffer overflow.

- buf is returned on line 469 and errno is not set.

This resolves BZ #28769.

Reviewed-by: Andreas Schwab <schwab@linux-m68k.org>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
Signed-off-by: Qualys Security Advisory <qsa@qualys.com>
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
2024-01-12 23:20:06 +00:00
Florian Weimer ac5b880423 CVE-2018-19591: if_nametoindex: Fix descriptor for overlong name [BZ #23927] 2024-01-12 23:20:06 +00:00
Florian Weimer 66bec53f07 CVE-2016-10739: getaddrinfo: Fully parse IPv4 address strings [BZ #20018]
Some tests in original commit are not included because they depend on headers that
are not present in GRTEv5 branch.

The IPv4 address parser in the getaddrinfo function is changed so that
it does not ignore trailing whitespace and all characters after it.
For backwards compatibility, the getaddrinfo function still recognizes
legacy name syntax, such as 192.000.002.010 interpreted as 192.0.2.8
(octal).

This commit does not change the behavior of inet_addr and inet_aton.
gethostbyname already had additional sanity checks (but is switched
over to the new __inet_aton_exact function for completeness as well).

To avoid sending the problematic query names over DNS, commit
6ca53a2453 ("resolv: Do not send queries
for non-host-names in nss_dns [BZ #24112]") is needed.
2024-01-12 23:19:48 +00:00
Pranav Kant 2b1ebe408a Typo in configure.ac
Fallback from 0778e25fe1
2024-01-03 22:03:34 +00:00
Pranav Kant 2d7ea00f76 Replace math-barriers with math_private
That's where the definition for math_force_eval was before refactoring
2023-12-29 00:36:58 +00:00
Pranav Kant e371f141f9 Expose __isinff128 for clang 2023-12-29 00:19:59 +00:00
Adhemerval Zanella 66cff6cd8a x86_64: Add SSE sfp-exceptions
The exported x86_64 fenv.h functions operate on both i387 and SSE (since
they should work on both float, double, and long double) while the
internal libc_fe* set either SSE (float, double, and float128) or
i387 (long double).

The libgcc __sfp_handle_exceptions (used on float128 implementation),
however, will set either SEE or i387 exception depending of the
exception to raise.  This broke the internal assumption of float128
where only SSE operations will be used.

This patch reimplements the libgcc __sfp_handle_exceptions to use only
SSE operations and sets libgcc to use it instead of its own
implementation.

And I think we should fix libgcc in a similar manner, since checking on
config/i386/64/sfp-machine.h it already only supports SSE rounding mode
and x86_64 ABI also expectes float128 to use SSE registers [1]
(although it is not clear on how future implementation might implement
it).

Checked on x86_64-linux-gnu.

[1] https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI
2023-12-28 23:45:34 +00:00
Pranav Kant 0778e25fe1 Sync configure.ac with configure script
Fallback from bade6276d1
2023-12-28 22:49:47 +00:00
Pranav Kant 5ac69deee6 Get rid of WANT_FLOAT128 usage in floatn.h
This header is installed system-wide. It's not correct to introduce a new
macro WANT_FLOAT128 in this because then we are either forcing the compiler to
make it an inbuilt macro to make glibc expose all float128 functionality, or asking
our clients to -DWANT_FLOAT128 to get float128 functionality in glibc.

Given we are primarily going to have float128 enabled GRTE now, we don't need to have
guards for non-float128 cases.
2023-12-28 22:46:32 +00:00
Pranav Kant 57afddcb68 -DWANT_FLOAT usage and enable float128 tests 2023-12-27 22:22:08 +00:00
Pranav Kant 60417c3867 x86: Respect --disable-float128 flag to disable FLOAT128 functionality 2023-09-28 00:09:32 +00:00
Fangrui Song 2676793257 x86: Define __HAVE_FLOAT128 for Clang and use __builtin_*f128 code path
Clang supports __builtin_fabsf128 (despite not supporting _Float128) but
_not _builtin_fabsq.
By falling back to `typedef __float128 _Float128;`, the float128 code
will be buildable with Clang.
2023-09-27 19:05:16 +00:00
Pranav Kant bade6276d1 configure: Use same pattern to find headers for clang 2023-09-27 19:03:26 +00:00
Adhemerval Zanella aacd7e0eb6 math: x86: Use prefix for FP_INIT_ROUNDMODE
Not all compilers support the inline asm prefix '%v' to emit the avx
instruction if AVX is enable.  Use a prefix instead.

Checked on x86_64-linux-gnu and i686-linux-gnu.
2023-09-27 19:03:26 +00:00
Pranav Kant fe59db4d1b Avoid error due to -Wimplicit-function-declaration 2023-09-26 19:03:26 +00:00
Adhemerval Zanella 950a6559ad math: x86: Avoid the use of __libgcc_cmp_return__ for __gcc_CMPtype 2023-09-26 19:02:33 +00:00
Fangrui Song 3697387eab Add -Wl,--undefined-version when using newer lld
to work around errors like

    version script assignment of 'GLIBC_2.4' to symbol '__stack_chk_guard' failed: symbol not defined
2023-08-29 03:31:31 +00:00
Paul Pluzhnikov 2dda6eab52 Apply upstream commit __builtin_FILE commit to GRTEv5.
https://sourceware.org/git/?p=glibc.git;a=commit;h=e42ec822190056895e55e5140ce2304e67e34445
2023-02-10 20:40:56 +00:00
Nilay Vaish 16ca0733a0 nptl: Make mmap and munmap in thread stack allocation interposable
b/238021577: __mmap and __munmap are not interposable.  Call
interposable mmap and munmap instead so that we can capture thread stack
allocations.
2022-10-27 11:33:58 -07:00
Joseph Myers 7255e947f2 Fix build of nptl/tst-thread_local1.cc with GCC 12
The test nptl/tst-thread_local1.cc fails to build with GCC mainline
because of changes to what libstdc++ headers implicitly include what
other headers:

tst-thread_local1.cc: In function 'int do_test()':
tst-thread_local1.cc:177:5: error: variable 'std::array<std::pair<const char*, std::function<void(void* (*)(void*))> >, 2> do_thread_X' has initializer but incomplete type
  177 |     do_thread_X
      |     ^~~~~~~~~~~

Fix this by adding an explicit include of <array>.

Tested with build-many-glibcs.py for aarch64-linux-gnu.

(cherry picked from commit 2ee9b24f47)
2022-10-27 11:29:56 -07:00
Kamlesh Kumar 2fa202fdd1 <string.h>: Define __CORRECT_ISO_CPP_STRING_H_PROTO for Clang [BZ #25232]
Without the asm redirects, strchr et al. are not const-correct.

libc++ has a wrapper header that works with and without
__CORRECT_ISO_CPP_STRING_H_PROTO (using a Clang extension).  But when
Clang is used with libstdc++ or just C headers, the overloaded functions
with the correct types are not declared.

This change does not impact current GCC (with libstdc++ or libc++).

(cherry picked from commit 953ceff17a)
2022-05-24 21:21:05 -07:00
Fangrui Song 20f6c92422 Makeconfig: Update clang_rt.crtbegin.o filename 2022-05-02 21:01:43 -07:00
Fangrui Song 15c4b8cbcc Remove x86_64 specific lowlevellock/cancellation
The x86_64 specific implemention has CFI directives like
`.cfi_adjust_cfa_offset 128` which are incorrect when RBP is used as the
canonical frame address.

This follows the spirit of the following two commits by removing the
x86_64 specific implementation. The generic implementation will be used.

* eb76e5b465 ("nptl: Reinstate pthread_timedjoin_np as a cancellation point (BZ#24215)")
* c50e1c263e ("x86: Remove arch-specific low level lock implementation")
2022-04-27 14:01:19 -07:00
Fangrui Song da683b1f10 elf: Support DT_RELR relative relocation format
Adapted from
https://sourceware.org/pipermail/libc-alpha/2022-April/138085.html
([PATCH v11 0/7] Support DT_RELR relative relocation format),
which is expected to be included in glibc 2.36.

glibc 2.35 has a fair amount of rtld changes to avoid nested functions
(https://sourceware.org/PR27220). This patch is carefully crafted to
make the minimal changes.

Notebly, this commit

* works around b/208156916 by not bumping DT_NUM. DT_RELR and DT_RELRSZ
  take the l_info slots at DT_VERSYM+1 and DT_VERSYM+2.
* avoids changes to include/link.h
* removes the time travel compatibility check (error if DT_RELR is used
  without GLIBC_ABI_DT_RELR version need). This needs link.h change and
  the detected case cannot happen if we correctly use
  -Wl,-z,pack-relative-relocs.
2022-04-25 16:50:00 -07:00
Fangrui Song d3c732cb43 configure: Don't check LD -v --help for LIBC_LINKER_FEATURE
When LIBC_LINKER_FEATURE is used to check a linker option with the equal
sign, it will likely fail because the LD -v --help output may look like
`-z lam-report=[none|warning|error]` while the needle is something like
`-z lam-report=warning`.

The LD -v --help filter doesn't save much time, so just remove it.

(cherry picked from commit 8438135d34)
2022-04-25 16:48:25 -07:00
Joseph Myers c0a4365442 Use libc_hidden_* for atoi (bug 15105).
Continuing the fixes for localplt test failures with -Os arising from
functions not being inlined in that case, this patch fixes such
failures for atoi by using libc_hidden_proto and libc_hidden_def.

Tested for x86_64 (both that it removes this particular localplt
failure for -Os, and that the testsuite continues to pass without
-Os).

	[BZ #15105]
	* stdlib/atoi.c (atoi): Use libc_hidden_def.
	* include/stdlib.h [!_ISOMAC] (atoi): Use libc_hidden_proto.

(cherry picked from commit 20602c72fa)
2021-11-19 13:20:26 -08:00
Joseph Myers 98fa83a2a8 Use libc_hidden_* for tolower, toupper (bug 15105).
Continuing the fixes for localplt test failures with -Os arising from
functions not being inlined in that case, this patch fixes such
failures for tolower and toupper by using libc_hidden_proto and
libc_hidden_def.

Tested for x86_64 (both that it removes this particular localplt
failure for -Os, and that the testsuite continues to pass without
-Os).

2018-02-22  Joseph Myers  <joseph@codesourcery.com>

	[BZ #15105]
	* ctype/ctype.c (tolower): Use libc_hidden_def.
	(toupper): Likewise.
	* include/ctype.h [!_ISOMAC] (tolower): Use libc_hidden_proto.
	[!_ISOMAC] (toupper): Likewise.

(cherry picked from commit 54412d2061)
2021-11-19 13:20:26 -08:00
Joseph Myers bf291348a7 Use libc_hidden_* for argz_next, __argz_next (bug 15105).
Among other localplt test failures when building with -Os, there are
libc.so PLT references for argz_next and __argz_next.  This is a
simple case of functions that are inlined for -O2 but not for -Os;
this patch adds libc_hidden_proto / libc_hidden_def for them to avoid
localplt failures even when not inlined.

Tested for x86_64 (both that it removes these particular localplt
failures for -Os - but other such failures remain so the bug can't yet
be closed - and that the testsuite continues to pass without -Os).

	[BZ #15105]
	* include/argz.h (argz_next): Use libc_hidden_proto.
	(__argz_next): Likewise.
	* string-argz-next.c (__argz_next): Use libc_hidden_def.
	(argz_next): Use libc_hidden_weak.

(cherry picked from commit 055ac2a7ee)
2021-11-19 13:20:26 -08:00
Joseph Myers 633d14073f Use libc_hidden_* for __cmsg_nxthdr (bug 15105).
Among other localplt test failures when building with -Os, there are
libc.so PLT references for __cmsg_nxthdr.  This is a simple case of a
function that is inlined for -O2 but not for -Os; this patch adds
libc_hidden_proto / libc_hidden_def for it to avoid a localplt failure
even when it is not inlined.

Tested for x86_64 (both that it removes this particular localplt
failure for -Os - but other such failures remain so the bug can't yet
be closed - and that the testsuite continues to pass without -Os).

	[BZ #15105]
	* include/sys/socket.h [!_ISOMAC] (__cmsg_nxthdr): Use
	libc_hidden_proto.
	* sysdeps/unix/sysv/linux/cmsg_nxthdr.c (__cmsg_nxthdr): Use
	libc_hidden_def.

(cherry picked from commit e4452a2d19)
2021-11-19 13:20:26 -08:00
Joseph Myers d7c1214f4d Use libc_hidden_* for fputs (bug 15105).
Among other localplt test failures when building with -Os, there are
libc.so PLT references for fputs.  fputs calls normally get redirected
to _IO_fputs by a macro in include/stdio.h (and _IO_fputs in turn uses
libc_hidden_proto), but GCC can convert an fprintf call with a
constant string argument into an fputs call, which of course is then
unaffected by the macro redirection.  (I don't know why this issue
only appears with -Os.)

This patch duly adds a use of libc_hidden_proto for fputs.  I see no
obvious reason why the fputs macro redirection is needed at all, but
this patch does not change it.

Tested for x86_64 (both that it removes this particular localplt
failure for -Os - but other such failures remain so the bug can't yet
be closed - and that the testsuite continues to pass without -Os).

	[BZ #15105]
	* include/stdio.h [!_ISOMAC && IS_IN (libc)] (fputs): Use
	libc_hidden_proto.
	* libio/iofputs.c (fputs): Use libc_hidden_weak.

(cherry picked from commit 499b315324)
2021-11-19 13:20:26 -08:00
Joseph Myers aac0d8a9a3 Fix -Os gnu_dev_* linknamespace, localplt issues (bug 15105, bug 19463).
Building with -Os produces linknamespace and localplt failures for,
among other functions, gnu_dev_major, gnu_dev_minor and
gnu_dev_makedev.

The issue is that those functions are not inlined when building with
-Os.  While one could force them to be inlined in that case, it seems
more natural to fix this issue similarly to other namespace issues.
Thus, this patch makes gnu_dev_* into weak aliases for hidden symbols
__gnu_dev_*; __gnu_dev_* are then defined as inlines in the internal
include/sys/sysmacros.h, and uses of gnu_dev_* (often via the macros
major, minor and makedev) for which there are namespace issues are
changed to use __gnu_dev_*; where there are no namespace issues, use
of libc_hidden_proto serves to avoid unnecessary local PLT entry use.

Tested for x86_64, (a) without -Os, to verify the testsuite continues
to pass without problems and that the functions called under their new
names continue to be inlined as expected in that case; (b) with -Os,
to verify that the linknamespace and localplt failures in question go
away (but because of other such failures present, neither of the
relevant bugs can yet be closed).

	[BZ #15105]
	[BZ #19463]
	* include/sys/sysmacros.h [!_ISOMAC]
	(__SYSMACROS_NEED_IMPLEMENTATION): Define macro.
	[!_SYS_SYSMACROS_H_WRAPPER && !_ISOMAC]
	(_SYS_SYSMACROS_H_WRAPPER): Likewise.
	[!_SYS_SYSMACROS_H_WRAPPER && !_ISOMAC] (gnu_dev_major): Use
	libc_hidden_proto.
	[!_SYS_SYSMACROS_H_WRAPPER && !_ISOMAC] (gnu_dev_minor): Likewise.
	[!_SYS_SYSMACROS_H_WRAPPER && !_ISOMAC] (gnu_dev_makedev):
	Likewise.
	[!_SYS_SYSMACROS_H_WRAPPER && !_ISOMAC] (__SYSMACROS_DECL_TEMPL):
	Undefine and redefine to add use __gnu_dev_ prefix.
	[!_SYS_SYSMACROS_H_WRAPPER && !_ISOMAC] (__SYSMACROS_IMPL_TEMPL):
	Likewise.
	[!_SYS_SYSMACROS_H_WRAPPER && !_ISOMAC] (__gnu_dev_major): Declare
	and define as hidden inline function.
	[!_SYS_SYSMACROS_H_WRAPPER && !_ISOMAC] (__gnu_dev_minor):
	Likewise.
	[!_SYS_SYSMACROS_H_WRAPPER && !_ISOMAC] (__gnu_dev_makedev):
	Likewise.
	* misc/makedev.c (OUT_OF_LINE_IMPL_TEMPL): Use __gnu_dev_ prefix.
	(gnu_dev_major): Use weak_alias and libc_hidden_weak.
	(gnu_dev_minor): Likewise.
	(gnu_dev_makedev): Likewise.
	* csu/check_fds.c (check_one_fd): Use __gnu_dev_makedev instead of
	makedev.
	* posix/wordexp.c (exec_comm_child): Likewise.
	* sysdeps/mach/hurd/xmknodat.c (__xmknodat): Use __gnu_dev_minor
	instead of minor and __gnu_dev_major instead of major.
	* sysdeps/unix/sysv/linux/device-nrs.h (DEV_TTY_P): Use
	__gnu_dev_major instead of major.
	* sysdeps/unix/sysv/linux/pathconf.c (distinguish_extX): Use
	__gnu_dev_major instead of gnu_dev_major and __gnu_dev_minor
	instead of gnu_dev_minor.
	* sysdeps/unix/sysv/linux/ptsname.c (MASTER_P): Likewise.
	(SLAVE_P): Likewise.
	(__ptsname_internal): Use __gnu_dev_minor instead of minor.
	* sysdeps/unix/sysv/linux/ttyname.h (is_pty): Use __gnu_dev_major
	instead of major.

(cherry picked from commit 8b4a118222)
2021-11-15 14:31:46 -08:00
Fangrui Song 903a6c6d5a install: Replace scripts/output-format.sed with objdump -f [BZ #26559]
GNU ld and gold have supported --print-output-format since 2011. glibc
requires binutils>=2.25 (2015), so if LD is GNU ld or gold, we can
assume the option is supported.

lld is by default a cross linker supporting multiple targets. It auto
detects the file format and does not need OUTPUT_FORMAT. It does not
support --print-output-format.

By parsing objdump -f, we can support all the three linkers.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
(cherry picked from commit 87d583c6e8)
2021-11-15 13:16:26 -08:00
Stan Shebs b0d12dcb63 Use a better workaround for clang lack of _builtin_va_arg_pack 2021-11-12 06:48:03 -08:00
Fangrui Song add8e34cd7 Set the retain attribute on _elf_set_element if CC supports [BZ #27492]
So that text_set_element/data_set_element/bss_set_element defined
variables will be retained by the linker.

Note: 'used' and 'retain' are orthogonal: 'used' makes sure the variable
will not be optimized out; 'retain' prevents section garbage collection
if the linker support SHF_GNU_RETAIN.

GNU ld 2.37 and LLD 13 will support -z start-stop-gc which allow C
identifier name sections to be GCed even if there are live
__start_/__stop_ references.

Without the change, there are some static linking problems, e.g.
_IO_cleanup (libio/genops.c) may be discarded by ld --gc-sections, so
stdout is not flushed on exit.

Note: GCC may warning 'retain' attribute ignored while __has_attribute(retain)
is 1 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99587).

Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
(cherry picked from commit cd6ae7ea54)
2021-08-31 15:36:41 -07:00
Fangrui Song bc129fb15b powerpc: Use --no-tls-get-addr-optimize in test only if the linker supports it
LLD doesn't support --{,no-}tls-get-addr-optimize.

Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
(cherry picked from commit f9cd7d5d19)
2021-08-27 17:27:51 -07:00
Fangrui Song 7334a4d5c3 elf: Drop elf/tls-macros.h in favor of __thread and tls_model attributes [BZ #28152] [BZ #28205]
elf/tls-macros.h was added for TLS testing when GCC did not support
__thread. __thread and tls_model attributes are mature now and have been
used by many newer tests.

Also delete tst-tls2.c which tests .tls_common (unused by modern GCC and
unsupported by Clang/LLD). .tls_common and .tbss definition are almost
identical after linking, so the runtime test doesn't add additional
coverage.  Assembler and linker tests should be on the binutils side.

When LLD 13.0.0 is allowed in configure.ac
(https://sourceware.org/pipermail/libc-alpha/2021-August/129866.html),
`make check` result is on par with glibc built with GNU ld on aarch64
and x86_64.

As a future clean-up, TLS_GD/TLS_LD/TLS_IE/TLS_IE macros can be removed from
sysdeps/*/tls-macros.h. We can add optional -mtls-dialect={gnu2,trad}
tests to ensure coverage.

Tested on aarch64-linux-gnu, powerpc64le-linux-gnu, and x86_64-linux-gnu.

Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
(cherry picked from commit 33c50ef428)
2021-08-27 17:26:09 -07:00
Fangrui Song e457303afe aarch64: Make elf_machine_{load_address,dynamic} robust [BZ #28203]
The AArch64 ABI is largely platform agnostic and does not specify
_GLOBAL_OFFSET_TABLE_[0] ([1]). glibc ld.so turns out to be probably the
only user of _GLOBAL_OFFSET_TABLE_[0] and GNU ld defines the value
to the link-time address _DYNAMIC. [2]

In 2012, __ehdr_start was implemented in GNU ld and gold in binutils
2.23.  Using adrp+add / (-mcmodel=tiny) adr to access
__ehdr_start/_DYNAMIC gives us a robust way to get the load address and
the link-time address of _DYNAMIC.

[1]: From a psABI maintainer, https://bugs.llvm.org/show_bug.cgi?id=49672#c2
[2]: LLD's aarch64 port does not set _GLOBAL_OFFSET_TABLE_[0] to the
link-time address _DYNAMIC.
LLD is widely used on aarch64 Android and ChromeOS devices.  Software
just works without the need for _GLOBAL_OFFSET_TABLE_[0].

Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
(cherry picked from commit 43d06ed218)
2021-08-27 17:26:09 -07:00
Fangrui Song ec38ea9597 elf: Unconditionally use __ehdr_start
We can consider __ehdr_start (from binutils 2.23 onwards)
unconditionally supported, since configure.ac requires binutils>=2.25.

The configure.ac check is related to an ia64 bug fixed by binutils 2.24.
See https://sourceware.org/pipermail/libc-alpha/2014-August/053503.html

Tested on x86_64-linux-gnu. Tested build-many-glibcs.py with
aarch64-linux-gnu and s390x-linux-gnu.

Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
(cherry picked from commit 302247c891)
2021-08-27 17:26:09 -07:00
Andreas Schwab 6056776143 wordexp: handle overflow in positional parameter number (bug 28011)
Use strtoul instead of atoi so that overflow can be detected.
2021-08-27 17:26:08 -07:00
Stan Shebs 359a244dc6 Disable tests that need more-recent infrastructure 2021-08-27 17:26:08 -07:00
Arjun Shankar 453aafef16 intl: Handle translation output codesets with suffixes [BZ #26383]
Commit 91927b7c76 (Rewrite iconv option parsing [BZ #19519]) did not
handle cases where the output codeset for translations (via the `gettext'
family of functions) might have a caller specified encoding suffix such as
TRANSLIT or IGNORE.  This led to a regression where translations did not
work when the codeset had a suffix.

This commit fixes the above issue by parsing any suffixes passed to
__dcigettext and adds two new test-cases to intl/tst-codeset.c to
verify correct behaviour.  The iconv-internal function __gconv_create_spec
and the static iconv-internal function gconv_destroy_spec are now visible
internally within glibc and used in intl/dcigettext.c.
2021-08-27 17:26:08 -07:00
Arjun Shankar 804887a0c8 Rewrite iconv option parsing [BZ #19519]
This commit replaces string manipulation during `iconv_open' and iconv_prog
option parsing with a structured, flag based conversion specification.  In
doing so, it alters the internal `__gconv_open' interface and accordingly
adjusts its uses.

This change fixes several hangs in the iconv program and therefore includes
a new test to exercise iconv_prog options that originally led to these hangs.
It also includes a new regression test for option handling in the iconv
function.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
2021-08-27 17:26:08 -07:00
Arjun Shankar 77d2c2fd0d iconv: Accept redundant shift sequences in IBM1364 [BZ #26224]
The IBM1364, IBM1371, IBM1388, IBM1390 and IBM1399 character sets
share converter logic (iconvdata/ibm1364.c) which would reject
redundant shift sequences when processing input in these character
sets.  This led to a hang in the iconv program (CVE-2020-27618).

This commit adjusts the converter to ignore redundant shift sequences
and adds test cases for iconv_prog hangs that would be triggered upon
their rejection.  This brings the implementation in line with other
converters that also ignore redundant shift sequences (e.g. IBM930
etc., fixed in commit 692de4b396).

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
2021-08-27 17:26:08 -07:00
Michael Colavita 1a8e6a6562 iconv: Fix incorrect UCS4 inner loop bounds (BZ#26923)
Previously, in UCS4 conversion routines we limit the number of
characters we examine to the minimum of the number of characters in the
input and the number of characters in the output. This is not the
correct behavior when __GCONV_IGNORE_ERRORS is set, as we do not consume
an output character when we skip a code unit. Instead, track the input
and output pointers and terminate the loop when either reaches its
limit.

This resolves assertion failures when resetting the input buffer in a step of
iconv, which assumes that the input will be fully consumed given sufficient
output space.
2021-08-27 17:26:08 -07:00
Florian Weimer f1d716a048 math/test-sinl-pseudo: Use stack protector only if available
This fixes commit 9333498794 ("Avoid ldbl-96 stack
corruption from range reduction of pseudo-zero (bug 25487).").
2021-08-27 17:26:08 -07:00
Joseph Myers 8c5a6bf813 Avoid ldbl-96 stack corruption from range reduction of pseudo-zero (bug 25487).
Bug 25487 reports stack corruption in ldbl-96 sinl on a pseudo-zero
argument (an representation where all the significand bits, including
the explicit high bit, are zero, but the exponent is not zero, which
is not a valid representation for the long double type).

Although this is not a valid long double representation, existing
practice in this area (see bug 4586, originally marked invalid but
subsequently fixed) is that we still seek to avoid invalid memory
accesses as a result, in case of programs that treat arbitrary binary
data as long double representations, although the invalid
representations of the ldbl-96 format do not need to be consistently
handled the same as any particular valid representation.

This patch makes the range reduction detect pseudo-zero and unnormal
representations that would otherwise go to __kernel_rem_pio2, and
returns a NaN for them instead of continuing with the range reduction
process.  (Pseudo-zero and unnormal representations whose unbiased
exponent is less than -1 have already been safely returned from the
function before this point without going through the rest of range
reduction.)  Pseudo-zero representations would previously result in
the value passed to __kernel_rem_pio2 being all-zero, which is
definitely unsafe; unnormal representations would previously result in
a value passed whose high bit is zero, which might well be unsafe
since that is not a form of input expected by __kernel_rem_pio2.

Tested for x86_64.
2021-08-27 17:26:08 -07:00
Adhemerval Zanella 6951b6ac39 posix: Sync gnulib regex implementation
This patch syncs the regex implementation with gnulib (commit 0ee5212).
Only two changes in GLIBC regex testing are required:

  1. posix/bug-regex28.c: as previously discussed [1] the change of
     expected results on the pattern should be safe.

  2. posix/PCRE.tests: the ERE (a)|\1 is malformed (in the sense that
     the \1 doesn't mean anything) and although current GLIBC accepts
     it has undefined behavior.  This patch removes the specific test.

This sync contains some patches from thread 'Regex: Make libc regex
more usable outside GLIBC.' [2] which have been pushed upstream in
gnulib.  This patches also fixes some regex issues (BZ #23233,
BZ #21163, BZ #18986, BZ #13762) and I did not add testcases for
both #23233 and #13762 because I couldn't think a simple way to
trigger the expected failure path to trigger them.

Checked on x86_64-linux-gnu and i686-linux-gnu.

	[BZ #23233]
	[BZ #21163]
	[BZ #18986]
	[BZ #13762]
	* posix/Makefile (tests): Add bug-regex37 and bug-regex38.
	* posix/PCRE.tests: Remove invalid test.
	* posix/bug-regex28.c: Fix expected values for used syntax.
	* posix/bug-regex37.c: New file.
	* posix/bug-regex38.c: Likewise.
	* posix/regcomp.c: Sync with gnulib.
	* posix/regex.c: Likewise.
	* posix/regex.h: Likewise.
	* posix/regex_internal.c: Likewise.
	* posix/regex_internal.h: Likewise.
	* posix/regexec.c: Likewise.

[1] https://sourceware.org/ml/libc-alpha/2017-12/msg00807.html
[2] https://sourceware.org/ml/libc-alpha/2017-12/msg00237.html
2021-08-27 17:26:07 -07:00
Andreas Schwab 2887b50077 Fix use-after-free in glob when expanding ~user (bug 25414)
The value of `end_name' points into the value of `dirname', thus don't
deallocate the latter before the last use of the former.
2021-08-27 17:26:07 -07:00
Stan Shebs 6db4535a70 Fix a return type in elf unload test 2021-08-27 17:26:07 -07:00
Andreas Schwab c0e9696c3c Fix buffer overrun in EUC-KR conversion module (bz #24973)
The byte 0xfe as input to the EUC-KR conversion denotes a user-defined
area and is not allowed.  The from_euc_kr function used to skip two bytes
when told to skip over the unknown designation, potentially running over
the buffer end.
2021-08-27 17:26:07 -07:00
Florian Weimer b3331e2d53 gconv: Fix assertion failure in ISO-2022-JP-3 module (bug 27256)
The conversion loop to the internal encoding does not follow
the interface contract that __GCONV_FULL_OUTPUT is only returned
after the internal wchar_t buffer has been filled completely.  This
is enforced by the first of the two asserts in iconv/skeleton.c:

	      /* We must run out of output buffer space in this
		 rerun.  */
	      assert (outbuf == outerr);
	      assert (nstatus == __GCONV_FULL_OUTPUT);

This commit solves this issue by queuing a second wide character
which cannot be written immediately in the state variable, like
other converters already do (e.g., BIG5-HKSCS or TSCII).

Reported-by: Tavis Ormandy <taviso@gmail.com>
2021-08-27 17:26:07 -07:00
Vitaly Buka 1515a92a53 Read f->func.cxa under the lock. 2021-08-27 17:26:07 -07:00
Ambrose Feinstein 22d31aef9e Fix bug where ld.so hashtable would retain strings passed to dlopen(). 2021-08-27 17:26:07 -07:00
Stan Shebs 282bbfc364 Extend elf/unload8 to test an additional load/unload pattern 2021-08-27 17:26:06 -07:00
Shu-Chun Weng 8238afcd89 Don't crash if /var/tmp doesn't exist
`xstat` is checked `stat64` crashing the program if the latter returns
failure. In this loop, we are trying to find one folder that satisfies
the condition, no reason to crash the program if one folder doesn't.
2021-08-27 17:26:06 -07:00
Shu-Chun Weng df64d52310 More aggressively prevent a buffer from being optimized out
The volatile global variable was first introduced in e86f9654c. I have
noticed the compiler still optimizing the buffer out on AArch64
presumably because the assignment is after all other observable
behaviors so it's still valid to eliminate it.
2021-08-27 17:26:06 -07:00
Fangrui Song a21d58a0dc x86_64: Remove unneeded static PIE check for undefined weak diagnostic
https://sourceware.org/bugzilla/show_bug.cgi?id=21782 dropped an ld
diagnostic for R_X86_64_PC32 referencing an undefined weak symbol in
-pie links.  Arguably keeping the diagnostic like other ports is more
correct, since statically resolving movl foo(%rip), %eax to the
link-time zero address produces a corrupted output.

It turns out that --enable-static-pie builds do not depend on the ld
behavior. GCC generates GOT indirection for weak declarations for
-fPIE/-fPIC, so what ld does with the PC-relative relocation doesn't
really matter.

Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
2021-08-27 17:26:06 -07:00
Wilco Dijkstra 2d20ffe431 [PATCH 7/7] sin/cos slow paths: refactor sincos implementation
Refactor the sincos implementation - rather than rely on odd partial inlining
of preprocessed portions from sin and cos, explicitly write out the cases.
This makes sincos much easier to maintain and provides an additional 16-20%
speedup between 0 and 2^27.  The overall speedup of sincos is 48% over this range.
Between 0 and PI it is 66% faster.

	* sysdeps/ieee754/dbl-64/s_sin.c (__sin): Cleanup ifdefs.
	(__cos): Likewise.
	* sysdeps/ieee754/dbl-64/s_sin.c (__sincos): Refactor using the same
	logic as sin and cos.
2021-08-27 17:26:06 -07:00
Wilco Dijkstra c8aaaf67f6 [PATCH 6/7] sin/cos slow paths: refactor duplicated code into dosin
Refactor duplicated code into do_sin.  Since all calls to do_sin use copysign to
set the sign of the result, move it inside do_sin.  Small inputs use a separate
polynomial, so move this into do_sin as well (the check is based on the more
conservative case when doing large range reduction, but could be relaxed).

	* sysdeps/ieee754/dbl-64/s_sin.c (do_sin): Use TAYLOR_SIN for small
	inputs.  Return correct sign.
	(do_sincos): Remove small input check before do_sin, let do_sin set
	the sign.
	(__sin): Likewise.
	(__cos): Likewise.
2021-08-27 17:26:06 -07:00
Wilco Dijkstra c015f0cc57 [PATCH 5/7] sin/cos slow paths: remove unused slowpath functions
Remove all unused slowpath functions.

	* sysdeps/ieee754/dbl-64/s_sin.c (TAYLOR_SLOW): Remove.
	(do_cos_slow): Likewise.
	(do_sin_slow): Likewise.
	(reduce_and_compute): Likewise.
	(slow): Likewise.
	(slow1): Likewise.
	(slow2): Likewise.
	(sloww): Likewise.
	(sloww1): Likewise.
	(sloww2): Likewise.
	(bslow): Likewise.
	(bslow1): Likewise.
	(bslow2): Likewise.
	(cslow2): Likewise.
2021-08-27 17:26:06 -07:00
Wilco Dijkstra d4d26acd8a [PATCH 4/7] sin/cos slow paths: remove slow paths from huge range reduction
For huge inputs use the improved do_sincos function as well.  Now no cases use
the correction factor returned by do_sin, do_cos and TAYLOR_SIN, so remove it.

	* sysdeps/ieee754/dbl-64/s_sin.c (TAYLOR_SIN): Remove cor parameter.
	(do_cos): Remove corp parameter and calculations.
	(do_sin): Likewise.
	(do_sincos): Remove cor variable.
	(__sin): Use do_sincos for huge inputs.
	(__cos): Likewise.
	* sysdeps/ieee754/dbl-64/s_sincos.c (__sincos): Likewise.
	(reduce_and_compute_sincos): Remove unused function.
2021-08-27 17:26:05 -07:00
Wilco Dijkstra 76f9784421 [PATCH 3/7] sin/cos slow paths: remove slow paths from small range reduction
This patch improves the accuracy of the range reduction.  When the input is
large (2^27) and very close to a multiple of PI/2, using 110 bits of PI is not
enough.  Improve range reduction accuracy to 136 bits.  As a result the special
checks for results close to zero can be removed.  The ULP of the polynomials is
at worst 0.55ULP, so there is no reason for the slow functions, and they can be
removed.

	* sysdeps/ieee754/dbl-64/s_sin.c (reduce_sincos_1): Rename to
	reduce_sincos, improve accuracy to 136 bits.
	(do_sincos_1): Rename to do_sincos, remove fallbacks to slow functions.
	(__sin): Use improved reduction and simplified do_sincos calculation.
	(__cos): Likewise.
	* sysdeps/ieee754/dbl-64/s_sincos.c (__sincos): Likewise.
2021-08-27 17:26:05 -07:00
Wilco Dijkstra e525ff25df [PATCH 2/7] sin/cos slow paths: remove large range reduction
This patch removes the large range reduction code and defers to the huge range
reduction code.  The first level range reducer supports inputs up to 2^27,
which is way too large given that inputs for sin/cos are typically small
(< 10), and optimizing for a smaller range would give a significant speedup.

Input values above 2^27 are practically never used, so there is no reason for
supporting range reduction between 2^27 and 2^48.  Removing it significantly
simplifies code and enables further speedups.  There is about a 2.3x slowdown
in this range due to __branred being extremely slow  (a better algorithm could
easily more than double performance).

	* sysdeps/ieee754/dbl-64/s_sin.c (reduce_sincos_2): Remove function.
	(do_sincos_2): Likewise.
	(__sin): Remove middle range reduction case.
	(__cos): Likewise.
	* sysdeps/ieee754/dbl-64/s_sincos.c (__sincos): Remove middle range
	reduction case.
2021-08-27 17:26:05 -07:00
Wilco Dijkstra bc57e68bbb [PATCH 1/7] sin/cos slow paths: avoid slow paths for small inputs
This series of patches removes the slow patchs from sin, cos and sincos.
Besides greatly simplifying the implementation, the new version is also much
faster for inputs up to PI (41% faster) and for large inputs needing range
reduction (27% faster).

ULP is ~0.55 with no errors found after testing 1.6 billion inputs across most
of the range with mpsin and mpcos.  The number of incorrectly rounded results
(ie. ULP >0.5) is at most ~2750 per million inputs between 0.125 and 0.5,
the average is ~850 per million between 0 and PI.

Tested on AArch64 and x86_64 with no regressions.

The first patch removes the slow paths for the cases where the input is small
and doesn't require range reduction.  Update ULP tables for sin, cos and sincos
on AArch64 and x86_64.

	* sysdeps/aarch64/libm-test-ulps: Update ULP for sin, cos, sincos.
	* sysdeps/ieee754/dbl-64/s_sin.c (__sin): Remove slow paths for small
	inputs.
	(__cos): Likewise.
	* sysdeps/x86_64/fpu/libm-test-ulps: Update ULP for sin, cos, sincos.
2021-08-27 17:26:05 -07:00
Lirong Yuan 5e46b24985 locale: Align _nl_C_LC_CTYPE_class and _nl_C_LC_CTYPE_class32
Otherwise, programs that use character classification macros such as
isspace may observe unaligned pointers.
2021-08-27 17:26:05 -07:00
Nick Lewycky 0ed6ae04d6 Change this offsetof computation to use c89 offsetof. Tested: 2021-08-27 17:26:05 -07:00
Stan Shebs bd1e10723b Update build process to create libnsl stub 2021-08-27 17:26:05 -07:00
Paul Pluzhnikov 87ac253d00 Forward-port google-nsl-stub 2021-08-27 17:26:04 -07:00
James Y Knight 04938f76dd Fix memory leak in TLS allocation 2021-08-27 17:26:04 -07:00
Stan Shebs bcc638805a Add a test of TLS support that will fail if leaky 2021-08-27 17:26:04 -07:00
Stan Shebs d548adb4ef Let time and gettimeofday use vdso by removing old clang workaround 2021-08-27 17:26:04 -07:00
Stan Shebs e62db8fce4 Use crt*.o files from llvm compiler-rt when building with clang 2021-08-27 17:26:04 -07:00
Stan Shebs 2c9e5207e4 Do not use ppc-specific long double pack/unpack when compiling with clang 2021-08-27 17:26:04 -07:00
Stan Shebs c3064d5f50 Remove old workaround in power7 logb functions, clang no longer crashes on the inline assembly 2021-08-27 17:26:04 -07:00
Josh Kunz cb90884046 Additional fixes for llvm-as
Unlike GCC, llvm always uses an integrated assembler, which attempts to
recognized all `asm` statements written in the C code. glibc uses some
syntactically invalid asm statements to emit constants into assembly that
are later extracted with a sed or AWK script.

This change fixes two such invalid `asm` statements by wrapping the
output in a `.ascii` directive.. This does not break the sed/AWK (the same
special sequence is output) but it makes the statement syntactically valid.

See cf8e3f8757 for a previous fix for the same issue.
2021-08-27 17:26:04 -07:00
Stan Shebs 144448d566 Add workaround for infinite looping in ppc vsyscall for sched_getcpu. 2021-08-27 17:26:03 -07:00
Stan Shebs 1ba3eb044d Add -Wno-incomplete-setjmp-declaration to prevent clang from unhelpfully complaining about __sigsetjmp, both in library build and testsuite runs. 2021-08-27 17:26:03 -07:00
Stan Shebs 86079708ee Update passwd.borg handling to use passwd.borg.real 2021-08-27 17:26:03 -07:00
Stan Shebs d0d7b3d2b3 Add a case to async-signal-safe TLS to set static TLS instead of waiting for a dlopen that may not actually be happening. 2021-08-27 17:26:03 -07:00
Stan Shebs 6a12504329 Add an LD_DEBUG=tls option to help debug thread-local storage handling in ld.so 2021-08-27 17:26:03 -07:00
Stan Shebs 396a77d48e Remove an unneeded local refactor in _dl_update_slotinfo 2021-08-27 17:26:03 -07:00
Joseph Myers 7d7724e795 Fix year 2039 bug for localtime with 64-bit time_t (bug 22639).
Bug 22639 reports localtime failing to handle time offset transitions
correctly in 2039 and later on platforms with 64-bit time_t.

The problem is the use of SECSPERDAY (constant 86400) in calculations
such as

    t = ((year - 1970) * 365
	 + /* Compute the number of leapdays between 1970 and YEAR
	      (exclusive).  There is a leapday every 4th year ...  */
	 + ((year - 1) / 4 - 1970 / 4)
	 /* ... except every 100th year ... */
	 - ((year - 1) / 100 - 1970 / 100)
	 /* ... but still every 400th year.  */
	 + ((year - 1) / 400 - 1970 / 400)) * SECSPERDAY;

where t is of type time_t and year is of type int.  Before my commit
92bd70fb85 (an update from tzcode,
included in 2.26 and later releases), SECSPERDAY was obtained from a
file imported from tzcode, where the value included a cast to
int_fast32_t.  On 64-bit platforms, glibc defines int_fast32_t to be
long int, so 64-bit, but my patch resulted in it changing to int.
(The bug would probably have existed even before my patch for x32,
which has 64-bit time_t but 32-bit int_fast32_t, but I haven't
verified that.)

This patch fixes the problem by including a cast to time_t in the
definition of SECSPERDAY.  (64-bit time support for 32-bit systems
should move such code that isn't a public interface to using the
internal 64-bit version of time_t throughout.)

Tested for x86_64 and x86.

	[BZ #22639]
	* time/tzset.c (SECSPERDAY): Cast to time_t.
	* time/tst-y2039.c: New file.
	* time/Makefile (tests): Add tst-y2039.
2021-08-27 17:26:03 -07:00
Stan Shebs 3a84f426fd Reduce __MAX_ALLOCA_CUTOFF to 8192 2021-08-27 17:26:02 -07:00
Stan Shebs c4d57c29b5 Make multi-arch ifunc support work with clang 2021-08-27 17:26:02 -07:00
Stan Shebs 66c8103bdf Revert clang workaround for _begin that is no longer needed 2021-08-27 17:26:02 -07:00
Ambrose Feinstein af63681769 Redesign the fastload support for additional performance 2021-08-27 17:26:02 -07:00
Josh Kunz 6733782381 Add comments explaining the diff from cf8e3f8757
These comments should make it easier to see the (small) diff introduced
in cf8e3f8757. Without these comments, the diff may get list on a future
upstream merge.
2021-08-27 17:26:02 -07:00
Josh Kunz ad41eacfb7 Make gen-XX-const scripts work with llvm-as
The gen-as-const and gen-py-const scripts are used to generate integer constant
definitions from a list of constant C-expressions. This is achieved by
generating a C program with inline `asm` statements, that depend on
these constant expressions. During compilation, the constant expressions
are evaluated, and included in the inline asm. The build process
generates only the assembly, and then used `sed` to extract the values
from the assembly text.

This is clever. It allows the build process to extract the value of C
statements built under the target architecture. The implementation is a
bit fragile, but it is not immediately obvious to me how it could be
improved.

This change slightly modifies `gen-as-const` and `gen-py-const` to emit
valid assembly directives instead of invalid directives that were
previously emitted. Since the values are extracted via string parsing,
this has no effect on the values extracted. This is needed because the
LLVM assembler validates all statements before emitting them, whereas it
appears GCC will literally emit any `asm` directives without validation
or recognition.
2021-08-27 17:26:02 -07:00
Stan Shebs 8d141ab782 Fix sense of a test in the static-linking version of ppc get_clockfreq 2021-08-27 17:26:02 -07:00
Shu-Chun Weng e1c6d2b0f4 Makes it compile for AArch64
De-nesting fix in 83c02e85 changed function signature but AArch64 was untested.
2021-08-27 17:26:01 -07:00
Shu-Chun Weng 83bede0cfc Makes AArch64 assembly acceptable to clang
According to ARMv8 architecture reference manual section C7.2.188, SIMD MOV (to
general) instruction format is

  MOV <Xd>, <Vn>.D[<index>]

gas appears to accept "<Vn>.2D[<index>]" as well, but clang's assembler does
not. C.f. https://community.arm.com/developer/ip-products/processors/f/cortex-a-forum/5214/aarch64-assembly-syntax-for-armclang
2021-08-27 17:26:01 -07:00
Siva Chandra Reddy 038be62f96 Include STATIC_PIE_BOOTSTRAP with !NESTING in powerpc64/dl-machine.h 2021-08-27 17:26:01 -07:00
Siva Chandra Reddy 6676d4161d Actuall use LLVM_OBJCOPY if available. 2021-08-27 17:26:01 -07:00
Siva Chandra Reddy 059f0081cf Use llvm-objcopy, if available, to remove the .llvm_addrsig sections. 2021-08-27 17:26:01 -07:00
Siva Chandra Reddy 738baca865 Enable relaxed relocations when building certain object files for x86_64. 2021-08-27 17:26:01 -07:00
Siva Chandra Reddy 0337af1396 Un-nest an include in dl-reloc-static-pie.c.
A corresponding adjustment in sysdeps/x86_64/dl-machine.h has also been
made.
2021-08-27 17:26:01 -07:00
Stan Shebs 43afb70033 Disable -mfloat128 for clang, lets power9 insns into power8 executables 2021-08-27 17:26:00 -07:00
Stan Shebs 895947a3ca Also work around clang bctrl issue in get_clockfreq.c 2021-08-27 17:26:00 -07:00
Zack Weinberg b930ad424b [BZ #19239] Don't include sys/sysmacros.h from sys/types.h.
This completes the deprecation and removal of this inclusion, which
was begun in the 2.25 release.

	* posix/sys/types.h: Don't include sys/sysmacros.h.
	* misc/sys/sysmacros.h: Remove the conditional deprecation
	warnings for the macros defined by this header.
2021-08-27 17:26:00 -07:00
Stan Shebs c4c787ff1b Remove .llvm_addrsig sections from crt.o files 2021-08-27 17:26:00 -07:00
Brooks Moses b1ecb7cf85 Forward-port cl/42676407 to disable link-time warning about mktemp, tempnam and tmpnam. 2021-08-27 17:23:15 -07:00
Raman Tenneti 9e8081d123 Changes to compile glibc-2.27 on PPC (Power8) with clang.
+ Use DOT_MACHINE macro instead of ".machine" instruction.
+ Use __isinf and __isinff instead of builtin versions.
+ In s_logb, s_logbf and s_logbl functions, used float versions to
  calculate "ret = x & 0x7f800000;" expression.
2021-08-27 17:23:15 -07:00
Stan Shebs 91da896a3e Add a note about passwd.borg.base organization 2021-08-27 17:23:15 -07:00
Stan Shebs c51bab1714 Fix mistaken order of arguments to open_path 2021-08-27 17:23:15 -07:00
Stan Shebs b2d0b20ae6 Update build notes 2021-08-27 17:23:15 -07:00
Raman Tenneti bb9e16c6ea Undid the dl_enable_fastload environment variable changes. 2021-08-27 17:23:15 -07:00
Paul Pluzhnikov 590786950c Add "fastload" support. 2021-08-27 17:23:15 -07:00
Stan Shebs 3372bfe221 Work around lack of mfppr in clang 2021-08-27 17:23:14 -07:00
Stan Shebs 960ba7975c Work around mtfsb0 syntax limitation with clang 2021-08-27 17:23:14 -07:00
Stan Shebs e04e10b431 Avoid passing gcc-specific options to clang 2021-08-27 17:23:14 -07:00
Stan Shebs 452fe68a53 Make asm-based constraints be gcc-only 2021-08-27 17:23:14 -07:00
Stan Shebs 4b86f820b8 Make xxland syntax gcc-only 2021-08-27 17:23:14 -07:00
Stan Shebs 5e4f72b895 Add a first approximation of float definitions for ppc clang 2021-08-27 17:23:14 -07:00
Stan Shebs e21102f77e Make powerpc .machine directives be gcc-only 2021-08-27 17:23:14 -07:00
Stan Shebs bb112e11de Make mutex hints gcc-only, improve a type in __arch_compare_and_exchange_bool_32_acq 2021-08-27 17:23:14 -07:00
Stan Shebs 7724302310 Make power6 directives be gcc-only 2021-08-27 17:23:13 -07:00
Stan Shebs 1e88b203b3 Add power9 flag to go with -mfloat128 2021-08-27 17:23:13 -07:00
Stan Shebs 6fd7bec86f Disable more attempts to pass -mlong-double-128 to clang 2021-08-27 17:23:13 -07:00
Stan Shebs d21dfbccdc Disable attempts to pass -mlong-double-128 to clang 2021-08-27 17:23:13 -07:00
Stan Shebs acf11f4420 Add workaround for clang link failure in elf/tst-unique4 2021-08-27 17:23:13 -07:00
Stan Shebs b2d69ea7ac Add workaround for infinite looping in ppc vsyscalls 2021-08-27 17:23:13 -07:00
Stan Shebs 6ea6782b69 Work around clang crash by skipping apparently-unneeded asm 2021-08-27 17:23:13 -07:00
Stan Shebs b35774068a Work around clang problem with ifuncs and vdso 2021-08-27 17:23:12 -07:00
Stan Shebs 96509a9dce Work around a ppc clang inlining bug 2021-08-27 17:23:12 -07:00
Stan Shebs 9b6c937b00 Add workaround for segfaults in __longjmp when compiled with ppc clang 2021-08-27 17:23:12 -07:00
Stan Shebs f9bd60b7c0 Add clang version of find_cxx_header 2021-08-27 17:23:12 -07:00
Stan Shebs 0f93e3333f Change de-nesting fix to use added argument instead of globals 2021-08-27 17:23:12 -07:00
Stan Shebs 21991760c7 Fix regressions in async-safe TLS, add run-time control for debugging, add more comments 2021-08-27 17:23:12 -07:00
Stan Shebs c0ab16f8cc Fix TLS problems not handled by cherrypick 2021-08-27 17:23:12 -07:00
Brooks Moses 3e9a530aae Revert upstream removal of async-safe TLS patches. 2021-08-27 17:23:11 -07:00
Stan Shebs 74f10c8aad Make pointer in tst-realloc volatile also 2021-08-27 17:23:11 -07:00
Stan Shebs 5884367eb9 Add a GRTE-specific readme. 2021-08-27 17:23:07 -07:00
Stan Shebs 4d4222dd27 Work around a make 3.81 segfault with clang 2021-08-27 16:22:14 -07:00
Florian Weimer 121dc10a6d NEWS: Move security-lated changes before bug list
This matches the practice for previous releases.
2021-08-27 16:22:13 -07:00
Florian Weimer 537386b1c9 Add references to CVE-2018-11236, CVE-2017-18269 2021-08-27 16:22:13 -07:00
H.J. Lu 3eb848f535 Add a test case for [BZ #23196]
[BZ #23196]
	* string/test-memcpy.c (do_test1): New function.
	(test_main): Call it.

(cherry picked from commit ed983107bb)
2021-08-27 16:22:13 -07:00
Andreas Schwab c4fde9669a Don't write beyond destination in __mempcpy_avx512_no_vzeroupper (bug 23196)
When compiled as mempcpy, the return value is the end of the destination
buffer, thus it cannot be used to refer to the start of it.

(cherry picked from commit 9aaaab7c6e)
2021-08-27 16:22:13 -07:00
Florian Weimer da768de04f sunrpc: Remove stray exports without --enable-obsolete-rpc [BZ #23166]
This is needed to avoid a warning when linking against libtirpc:

/lib64/libc.so.6: warning: common of `rpc_createerr@@TIRPC_0.3.0' overridden by definition
/usr/lib64/libtirpc.so: warning: defined here

This ld warning is not enabled by default; -Wl,--warn-common enables it.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>

(cherry picked from commit 89aacb513e)
2021-08-27 16:22:13 -07:00
Rafal Luzynski 0c65d0085d gd_GB: Fix typo in abbreviated "May" (bug 23152).
[BZ #23152]
	* localedata/locales/gd_GB (abmon): Fix typo in May:
	"Mhàrt" -> "Cèit".  Adjust the comment according to the change.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit bb066cb806)
2021-08-27 16:22:12 -07:00
Dmitry V. Levin dd5ed1e875 NEWS: add entries for bugs 17343, 20419, 22644, 22786, 22884, 22947, 23005, 23037, 23069, 23137 2021-08-27 16:22:12 -07:00
Paul Pluzhnikov 1073cbb0ba Fix path length overflow in realpath [BZ #22786]
Integer addition overflow may cause stack buffer overflow
when realpath() input length is close to SSIZE_MAX.

2018-05-09  Paul Pluzhnikov  <ppluzhnikov@google.com>

	[BZ #22786]
	* stdlib/canonicalize.c (__realpath): Fix overflow in path length
	computation.
	* stdlib/Makefile (test-bz22786): New test.
	* stdlib/test-bz22786.c: New test.

(cherry picked from commit 5460617d15)
2021-08-27 16:22:12 -07:00
Paul Pluzhnikov c13e59843a Fix stack overflow with huge PT_NOTE segment [BZ #20419]
A PT_NOTE in a binary could be arbitratily large, so using alloca
for it may cause stack overflow.  If the note is larger than
__MAX_ALLOCA_CUTOFF, use dynamically allocated memory to read it in.

2018-05-05  Paul Pluzhnikov  <ppluzhnikov@google.com>

	[BZ #20419]
	* elf/dl-load.c (open_verify): Fix stack overflow.
	* elf/Makefile (tst-big-note): New test.
	* elf/tst-big-note-lib.S: New.
	* elf/tst-big-note.c: New.

(cherry picked from commit 0065aaaaae)
2021-08-27 16:22:12 -07:00
Stefan Liebler b3356fb4a1 Fix blocking pthread_join. [BZ #23137]
On s390 (31bit) if glibc is build with -Os, pthread_join sometimes
blocks indefinitely. This is e.g. observable with
testcase intl/tst-gettext6.

pthread_join is calling lll_wait_tid(tid), which performs the futex-wait
syscall in a loop as long as tid != 0 (thread is alive).

On s390 (and build with -Os), tid is loaded from memory before
comparing against zero and then the tid is loaded a second time
in order to pass it to the futex-wait-syscall.
If the thread exits in between, then the futex-wait-syscall is
called with the value zero and it waits until a futex-wake occurs.
As the thread is already exited, there won't be a futex-wake.

In lll_wait_tid, the tid is stored to the local variable __tid,
which is then used as argument for the futex-wait-syscall.
But unfortunately the compiler is allowed to reload the value
from memory.

With this patch, the tid is loaded with atomic_load_acquire.
Then the compiler is not allowed to reload the value for __tid from memory.

ChangeLog:

	[BZ #23137]
	* sysdeps/nptl/lowlevellock.h (lll_wait_tid):
	Use atomic_load_acquire to load __tid.

(cherry picked from commit 1660901840)
2021-08-27 16:22:12 -07:00
Joseph Myers 1ab675ca63 Add PTRACE_SECCOMP_GET_METADATA from Linux 4.16 to sys/ptrace.h.
This patch adds the PTRACE_SECCOMP_GET_METADATA constant from Linux
4.16 to all relevant sys/ptrace.h files.  A type struct
__ptrace_seccomp_metadata, analogous to other such types, is also
added.

Tested for x86_64, and with build-many-glibcs.py.

	* sysdeps/unix/sysv/linux/sys/ptrace.h
	(PTRACE_SECCOMP_GET_METADATA): New enum value and macro.
	* sysdeps/unix/sysv/linux/bits/ptrace-shared.h
	(struct __ptrace_seccomp_metadata): New type.
	* sysdeps/unix/sysv/linux/aarch64/sys/ptrace.h
	(PTRACE_SECCOMP_GET_METADATA): Likewise.
	* sysdeps/unix/sysv/linux/arm/sys/ptrace.h
	(PTRACE_SECCOMP_GET_METADATA): Likewise.
	* sysdeps/unix/sysv/linux/ia64/sys/ptrace.h
	(PTRACE_SECCOMP_GET_METADATA): Likewise.
	* sysdeps/unix/sysv/linux/powerpc/sys/ptrace.h
	(PTRACE_SECCOMP_GET_METADATA): Likewise.
	* sysdeps/unix/sysv/linux/s390/sys/ptrace.h
	(PTRACE_SECCOMP_GET_METADATA): Likewise.
	* sysdeps/unix/sysv/linux/sparc/sys/ptrace.h
	(PTRACE_SECCOMP_GET_METADATA): Likewise.
	* sysdeps/unix/sysv/linux/tile/sys/ptrace.h
	(PTRACE_SECCOMP_GET_METADATA): Likewise.
	* sysdeps/unix/sysv/linux/x86/sys/ptrace.h
	(PTRACE_SECCOMP_GET_METADATA): Likewise.

(cherry picked from commit 9320ca88a1)
2021-08-27 16:22:11 -07:00
Florian Weimer 43092e2ec2 resolv: Fully initialize struct mmsghdr in send_dg [BZ #23037]
(cherry picked from commit 583a27d525)
2021-08-27 16:22:11 -07:00
Florian Weimer adb65ebdcd manual: Various fixes to the mbstouwcs example, and mbrtowc update
The example did not work because the null byte was not converted, and
mbrtowc was called with a zero-length input string.  This results in a
(size_t) -2 return value, so the function always returns NULL.

The size computation for the heap allocation of the result was
incorrect because it did not deal with integer overflow.

Error checking was missing, and the allocated memory was not freed on
error paths.  All error returns now set errno.  (Note that there is an
assumption that free does not clobber errno.)

The slightly unportable comparision against (size_t) -2 to catch both
(size_t) -1 and (size_t) -2 return values is gone as well.

A null wide character needs to be stored in the result explicitly, to
terminate it.

The description in the manual is updated to deal with these finer
points.  The (size_t) -2 behavior (consuming the input bytes) matches
what is specified in ISO C11.

(cherry picked from commit cf138b0c83)
(cherry picked from commit 690c3475f1)
2021-08-27 16:22:11 -07:00
Florian Weimer d6df404c01 manual: Move mbstouwcs to an example C file
(cherry picked from commit 0f33925269)
2021-08-27 16:22:10 -07:00
H.J. Lu c01dc8b1ff Update RWF_SUPPORTED for Linux kernel 4.16 [BZ #22947]
Add RWF_APPEND to RWF_SUPPORTED to support Linux kernel 4.16.

	[BZ #22947]
	* bits/uio-ext.h (RWF_APPEND): New.
	* sysdeps/unix/sysv/linux/bits/uio-ext.h (RWF_APPEND): Likewise.
	* manual/llio.texi: Document RWF_APPEND.
	* misc/tst-preadvwritev2-common.c (RWF_APPEND): New.
	(RWF_SUPPORTED): Add RWF_APPEND.

(cherry picked from commit f2652643d7)
2021-08-27 16:22:10 -07:00
Jesse Hathaway dadc309087 getlogin_r: return early when linux sentinel value is set
When there is no login uid Linux sets /proc/self/loginid to the sentinel
value of, (uid_t) -1. If this is set we can return early and avoid
needlessly looking up the sentinel value in any configured nss
databases.

Checked on aarch64-linux-gnu.

	* sysdeps/unix/sysv/linux/getlogin_r.c (__getlogin_r_loginuid): Return
	early when linux sentinel value is set.

Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
(cherry picked from commit cc8a1620eb)
2021-08-27 16:22:10 -07:00
Andreas Schwab da41ab8923 Fix crash in resolver on memory allocation failure (bug 23005)
(cherry picked from commit f178e59fa5)
2021-08-27 16:22:09 -07:00
Joseph Myers 803f0773fb Fix signed integer overflow in random_r (bug 17343).
Bug 17343 reports that stdlib/random_r.c has code with undefined
behavior because of signed integer overflow on int32_t.  This patch
changes the code so that the possibly overflowing computations use
unsigned arithmetic instead.

Note that the bug report refers to "Most code" in that file.  The
places changed in this patch are the only ones I found where I think
such overflow can occur.

Tested for x86_64 and x86.

	[BZ #17343]
	* stdlib/random_r.c (__random_r): Use unsigned arithmetic for
	possibly overflowing computations.

(cherry picked from commit 8a07b0c43c)
2021-08-27 16:22:09 -07:00
Aurelien Jarno d0a2b24eb9 Add tst-sigaction.c to test BZ #23069
This simple test uses sigaction to define a signal handler. It then
uses sigaction again to fetch the information about the same signal
handler, and check that they are consistent. This is enough to detect
mismatches between struct kernel_sigaction and the kernel version of
struct sigaction, like in BZ #23069.

Changelog:
       * signal/tst-sigaction.c: New file to test BZ #23069.
       * signal/Makefile (tests): Fix indentation. Add tst-sigaction.

(cherry picked from commit 7a6f747871)
2021-08-27 16:22:09 -07:00
Aurelien Jarno b88e5137e6 RISC-V: fix struct kernel_sigaction to match the kernel version [BZ #23069]
The RISC-V kernel doesn't define SA_RESTORER, hence the kernel version
of struct sigaction doesn't have the sa_restorer field. The default
kernel_sigaction.h therefore can't be used.

This patch adds a RISC-V specific version of kernel_sigaction.h to fix
the issue. This fixes for example the libnih testsuite.

Note that this patch is not needed in master as the bug has been fixed
by commit b4a5d26d88 ("linux: Consolidate sigaction implementation").
2021-08-27 16:22:08 -07:00
Florian Weimer 80153017d1 Linux i386: tst-bz21269 triggers SIGBUS on some kernels
In addition to SIGSEGV and SIGILL, SIGBUS is also a possible signal
generated by the kernel.

(cherry picked from commit 4d76d3e59d)
2021-08-27 16:22:08 -07:00
Andrew Senkevich ee056103a0 Fix i386 memmove issue (bug 22644).
[BZ #22644]
	* sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S: Fixed
	branch conditions.
	* string/test-memmove.c (do_test2): New testcase.

(cherry picked from commit cd66c0e584)
2021-08-27 16:22:08 -07:00
DJ Delorie 35abf882dd Update ChangeLog for BZ 22884 - riscv fmax/fmin
(cherry picked from commit 7e04eb2932)
2021-08-27 16:22:08 -07:00
Andrew Waterman 012483cf93 RISC-V: fmax/fmin: Handle signalling NaNs correctly.
RISC-V's fmax(sNAN,4) returns 4 but glibc expects it to return qNAN.

	* sysdeps/riscv/rvd/s_fmax.c (__fmax): Handle sNaNs correctly.
	* sysdeps/riscv/rvd/s_fmin.c (__fmin): Likewise.
	* sysdeps/riscv/rvf/s_fmaxf.c (__fmaxf): Likewise.
	* sysdeps/riscv/rvf/s_fminf.c (__fminf): Likewise.

(cherry picked from commit fdcc625376)
2021-08-27 16:22:07 -07:00
DJ Delorie ab9c196492 RISC-V: Do not initialize $gp in TLS macros.
RISC-V TLS doesn't require GP to be initialized, and doing so breaks
TLS in a shared object.

(cherry picked from commit 8090720a87)
2021-08-27 16:22:07 -07:00
Rafal Luzynski c1b247e3c4 NEWS: Add entries for bugs: 22848, 22932, 22937, 22963.
Alternative (nominative/genitive) month names have been added to the
Catalan and Czech locale data and the abbreviated alternative names to
Catalan and Greek.

(cherry picked from commit c553cd6f7e)
2021-08-27 16:22:07 -07:00
Rafal Luzynski 88b3498548 cs_CZ locale: Add alternative month names (bug 22963).
Add alternative month names, primary month names are genitive now.

	[BZ #22963]
	* localedata/locales/cs_CZ (mon): Rename to...
	(alt_mon): This.
	(mon): Import from CLDR (genitive case).

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 807fee29d2)
2021-08-27 16:22:06 -07:00
Rafal Luzynski 07f3103a27 Greek (el_CY, el_GR) locales: Introduce ab_alt_mon (bug 22937).
As spotted by GNOME translation team, Greek language has the actually
visible difference between the abbreviated nominative and the abbreviated
genitive case for some month names.  Examples:

and more month names with similar differences.

Original discussion: https://bugzilla.gnome.org/show_bug.cgi?id=793645#c21

	[BZ #22937]
	* localedata/locales/el_CY (abmon): Rename to...
	(ab_alt_mon): This.
	(abmon): Import from CLDR (abbreviated genitive case).
	* localedata/locales/el_GR (abmon): Rename to...
	(ab_alt_mon): This.
	(abmon): Import from CLDR (abbreviated genitive case).

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit e7155a28ef)
2021-08-27 16:21:40 -07:00
Rafal Luzynski 2506b2401d lt_LT locale: Update abbreviated month names (bug 22932).
A GNOME translator asked to use the same abbreviated month names
as provided by CLDR.  This sounds reasonable.  See the discussion:
https://bugzilla.gnome.org/show_bug.cgi?id=793645#c27

	[BZ #22932]
	* localedata/locales/lt_LT (abmon): Synchronize with CLDR.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 71d7b12168)
2018-03-08 00:38:18 +01:00
Robert Buj a53136e6d8 ca_ES locale: Update LC_TIME (bug 22848).
Add/fix alternative month names, long & short formats, am_pm,
abday settings, and improve indentation for Catalan.

	[BZ #22848]
	* localedata/locales/ca_ES (abmon): Rename to...
	(ab_alt_mon): This, then synchronize with CLDR (nominative case).
	(mon): Rename to...
	(alt_mon): This.
	(abmon): Import from CLDR (genitive case, month names preceded by
	"de" or "d'").
	(mon): Likewise.
	(abday): Synchronize with CLDR.
	(d_t_fmt): Likewise.
	(d_fmt): Likewise.
	(am_pm): Likewise.

	(LC_TIME): Improve indentation.
	(LC_TELEPHONE): Likewise.
	(LC_NAME): Likewise.
	(LC_ADDRESS): Likewise.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit a00bffe8b5)
2018-03-06 22:51:29 +01:00
Dmitry V. Levin f6f3e83ea2 Update translations from the Translation Project
* po/pt_BR.po: Update translations.

(cherry picked from commit 778f197486)
2018-03-12 13:24:46 +00:00
Adhemerval Zanella 83d6db8187 i386: Fix i386 sigaction sa_restorer initialization (BZ#21269)
This patch fixes the i386 sa_restorer field initialization for sigaction
syscall for kernel with vDSO.  As described in bug report, i386 Linux
(and compat on x86_64) interprets SA_RESTORER clear with nonzero
sa_restorer as a request for stack switching if the SS segment is 'funny'.
This means that anything that tries to mix glibc's signal handling with
segmentation (for instance through modify_ldt syscall) is randomly broken
depending on what values lands in sa_restorer.

The testcase added  is based on Linux test tools/testing/selftests/x86/ldt_gdt.c,
more specifically in do_multicpu_tests function.  The main changes are:

  - C11 atomics instead of plain access.

  - Remove x86_64 support which simplifies the syscall handling and fallbacks.

  - Replicate only the test required to trigger the issue.

Checked on i686-linux-gnu.

	[BZ #21269]
	* sysdeps/unix/sysv/linux/i386/Makefile (tests): Add tst-bz21269.
	* sysdeps/unix/sysv/linux/i386/sigaction.c (SET_SA_RESTORER): Clear
	sa_restorer for vDSO case.
	* sysdeps/unix/sysv/linux/i386/tst-bz21269.c: New file.

(cherry picked from commit 68448be208)
2017-11-17 16:04:29 -02:00
Andreas Schwab bc7cdeb7f0 Fix multiple definitions of __nss_*_database (bug 22918)
(cherry picked from commit eaf6753f8a)
2018-03-02 23:07:14 +01:00
DJ Delorie 9a21941968 [BZ #22342] Fix netgroup cache keys.
Unlike other nscd caches, the netgroup cache contains two types of
records - those for "iterate through a netgroup" (i.e. setnetgrent())
and those for "is this user in this netgroup" (i.e. innetgr()),
i.e. full and partial records.  The timeout code assumes these records
have the same key for the group name, so that the collection of records
that is "this netgroup" can be expired as a unit.

However, the keys are not the same, as the in-netgroup key is generated
by nscd rather than being passed to it from elsewhere, and is generated
without the trailing NUL.  All other keys have the trailing NUL, and as
noted in the linked BZ, debug statements confirm that two keys for the
same netgroup are added to the cache with two different lengths.

The result of this is that as records in the cache expire, the purge
code only cleans out one of the two types of entries, resulting in
stale, possibly incorrect, and possibly inconsistent cache data.

The patch simply includes the existing NUL in the computation for the
key length ('key' points to the char after the NUL, and 'group' to the
first char of the group, so 'key-group' includes the first char to the
NUL, inclusive).

	[BZ #22342]
	* nscd/netgroupcache.c (addinnetgrX): Include trailing NUL in
	key value.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 1c81d55fc4)
2018-03-01 23:20:45 -05:00
Dmitry V. Levin fbac9a26b2 linux/powerpc: sync sys/ptrace.h with Linux 4.15 [BZ #22433, #22807]
Tested with strace.

* sysdeps/unix/sysv/linux/powerpc/sys/ptrace.h (__ptrace_request): Add
PTRACE_GETREGS, PTRACE_SETREGS, PTRACE_GETFPREGS, PTRACE_SETFPREGS,
PTRACE_GETVRREGS, PTRACE_SETVRREGS, PTRACE_GETEVRREGS,
PTRACE_SETEVRREGS, PTRACE_GETREGS64, PTRACE_SETREGS64,
PTRACE_GET_DEBUGREG, PTRACE_SET_DEBUGREG, PTRACE_GETVSRREGS,
PTRACE_SETVSRREGS, and PTRACE_SINGLEBLOCK.

(cherry picked from commit f5f473a9d0)
2018-02-10 23:19:32 +00:00
Tulio Magno Quites Machado Filho 3d67bc8070 powerpc: Undefine Linux ptrace macros that conflict with __ptrace_request
Linux ptrace headers define macros whose tokens conflict with the
constants of enum __ptrace_request causing build errors when
asm/ptrace.h or linux/ptrace.h are included before sys/ptrace.h.

	* sysdeps/unix/sysv/linux/powerpc/sys/ptrace.h: Undefine Linux
	macros used in __ptrace_request.

Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>
(cherry picked from commit 398c6fddaf)
2018-02-26 10:40:17 -03:00
Mike FABIAN 3e6bbf417e Add missing "reorder-end" in LC_COLLATE of et_EE [BZ #22517]
[BZ #22517]
	* localedata/locales/et_EE (LC_COLLATE): add missing "reorder-end"

(cherry picked from commit 7ec5f9465e)
2018-02-19 21:59:30 +01:00
Rical Jasan e157ee6889 Fix a typo in a comment.
* io/fcntl.h: Fix a typo in a comment.

(cherry picked from commit 0d217f4082)
2018-02-21 04:00:03 -08:00
Rical Jasan 064c0ff384 manual: Update the _ISOC99_SOURCE description.
The current description refers to ISO C99 not being widely adopted,
which it is believed to be now.

	* manual/creature.texi (_ISOC99_SOURCE): Update the dated
	description.

(cherry picked from commit e8d190b9ed)
2018-02-19 04:32:35 -08:00
Rical Jasan 438b279674 manual: Document missing feature test macros.
Several feature test macros are documented in features.h but absent in
the manual, and some documented macros accept undocumented values.
This commit updates the manual to mention all the accepted macros,
along with any values that hold special meaning.

	* manual/creature.texi (_POSIX_C_SOURCE): Document special
	values of 199606L, 200112L, and 200809L.
	(_XOPEN_SOURCE): Document special values of 600 and 700.
	(_ISOC11_SOURCE): Document macro.
	(_ATFILE_SOURCE): Likewise.
	(_FORTIFY_SOURCE): Likewise.

(cherry picked from commit 6a3962c4a4)
(cherry picked from commit da81ae645d)
2018-02-19 03:30:06 -08:00
Dmitry V. Levin 8044d7c6f7 NEWS: add entries for bugs 22919 and 22926 2018-03-08 23:30:56 +00:00
Aurelien Jarno 4d1ae634e6 sparc32: Add nop before __startcontext to stop unwinding [BZ #22919]
On sparc32 tst-makecontext fails, as backtrace called within a context
created by makecontext to yield infinite backtrace.

Fix that the same way than nios2 by adding a nop just before
__startcontext. This is needed as otherwise FDE lookup just repeatedly
finds __setcontext's FDE in an infinite loop, due to the convention of
using 'address - 1' for FDE lookup.

Changelog:
	[BZ #22919]
	* sysdeps/unix/sysv/linux/sparc/sparc32/setcontext.S (__startcontext):
	Add nop before __startcontext, add explaining comments.

(cherry picked from commit 9aa5c222b9)
2018-03-09 00:14:27 +01:00
Adhemerval Zanella f109026488 powerpc: Fix TLE build for SPE (BZ #22926)
Some SPE opcodes clashes with some recent PowerISA opcodes and
until recently gas did not complain about it.  However binutils
recently changed it and now VLE configured gas does not support to
assembler some instruction that might class with VLE (HTM for
instance).  It also does not help that glibc build hardware lock
elision support as default (regardless of assembler support).

Although runtime will not actually enables TLE on SPE hardware
(since kernel will not advertise it), I see little advantage on
adding HTM support on SPE built glibc.  SPE uses an incompatible
ABI which does not allow share the same build with default
powerpc and HTM code slows down SPE without any benefict.

This patch fixes it by only building HTM when SPE configuration
is not used.

Checked with a powerpc-linux-gnuspe build. I also did some sniff
tests on a e500 hardware without any issue.

	[BZ #22926]
	* sysdeps/powerpc/powerpc32/sysdep.h (ABORT_TRANSACTION_IMPL): Define
	empty for __SPE__.
	* sysdeps/powerpc/sysdep.h (ABORT_TRANSACTION): Likewise.
	* sysdeps/unix/sysv/linux/powerpc/elision-lock.c (__lll_lock_elision):
	Do not build hardware transactional code for __SPE__.
	* sysdeps/unix/sysv/linux/powerpc/elision-trylock.c
	(__lll_trylock_elision): Likewise.
	* sysdeps/unix/sysv/linux/powerpc/elision-unlock.c
	(__lll_unlock_elision): Likewise.

Cherry-pick from e921c89e01.
2018-03-05 14:46:24 -03:00
Rical Jasan 0c5e931cc0 manual: Improve documentation of get_current_dir_name. [BZ #6889]
This is a minor rewording to clarify the behaviour of
get_current_dir_name.  Additionally, the @vindex is moved above the
@deftypefun so that following links give a better result with regard
to context.

	[BZ #6889]
	* manual/filesys.texi (get_current_dir_name): Clarify
	behaviour.

(cherry picked from commit 7d15ef84f5)
2018-02-16 08:47:20 -08:00
Rical Jasan eea71a3beb manual: Fix a syntax error.
The opening parenthesis for function arguments in an @deftypefun need
to be separated from the function name.  This isn't just a matter of
the GNU coding style---it causes the "(void" (in this case) to be
rendered as a part of the function name, causing a visual defect, and
also results in a warning to the following effect during `make pdf':

  Warning: unbalanced parentheses in @def...)

	* manual/platform.texi (__riscv_flush_icache): Fix @deftypefun
	syntax.

(cherry picked from commit 16efad5171)
2018-02-16 08:21:47 -08:00
Rical Jasan a888c9b8b4 manual: Fix Texinfo warnings about improper node names.
A number of cross-references to the GCC info manual cause Texinfo
warnings; e.g.:

  ./creature.texi:11: warning: @xref node name should not contain `.'

This is due to "gcc.info" being used in the INFO-FILE-NAME (fourth)
argument.  Changing it to "gcc" removes these warnings.  (Manually
confirmed equivalent behaviour for make info, html, and pdf.)

	* manual/creature.texi: Convert references to gcc.info to gcc.
	* manual/stdio.texi: Likewise.
	* manual/string.texi: Likewise.

(cherry picked from commit 1f6676d7da)
2018-01-24 01:03:38 -08:00
Aurelien Jarno 3db5e60013 Fix posix/tst-glob_lstat_compat on alpha [BZ #22818]
The tst-glob_lstat_compat test needs to run tests on the previous
version of glob. On alpha, there are three versions of glob, GLIBC_2.0,
GLIBC_2.1 and GLIBC_2.27, while on other architectures there are only
the GLIBC_2.0 and GLIBC_2.27 version. Therefore on alpha the previous
version is GLIBC_2.1 and not GLIBC_2.0.

Changelog:
	[BZ #22818]
	* posix/tst-glob_lstat_compat.c [__alpha__] (glob): Access
	the GLIBC_2.1 version.

(cherry picked from commit f8d7958289)
2018-02-18 18:23:14 +01:00
Sean McKean a573a314d4 time: Reference CLOCKS_PER_SEC in clock comment [BZ #22735]
(cherry picked from commit 09e56b9e18)
2018-02-02 11:59:31 +01:00
Dmitry V. Levin 2d66557e88 linux/aarch64: sync sys/ptrace.h with Linux 4.15 [BZ #22433]
Remove compat-specific constants that were never exported by kernel
headers under these names.  Before linux commit v3.7-rc1~16^2~1 they
were exported with COMPAT_ prefix, and since that commit they are not
exported at all.

* sysdeps/unix/sysv/linux/aarch64/sys/ptrace.h (__ptrace_request):
Remove arm-specific PTRACE_GET_THREAD_AREA, PTRACE_GETHBPREGS,
and PTRACE_SETHBPREGS.

(cherry picked from commit 2fd4bbaa14)
2017-12-29 23:19:32 +00:00
Dmitry V. Levin 28def2cb11 NEWS: add an entry for bug 22827 2018-02-06 09:31:30 +00:00
Adhemerval Zanella 002eeb4cda Update SH libm-tests-ulps
* sysdeps/sh/libm-test-ulps: Update.

Signed-off-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
2018-02-14 14:03:13 -02:00
DJ Delorie 6cb1736f3a [RISC-V] Fix parsing flags in ELF64 files.
When ldconfig reads Elf64 files to determine the ABI, it used the
Elf32 type, so read the wrong location, and stored the wrong ABI
type in the cache, making the cache useless.  This patch uses
an Elf64 type for Elf64 objects instead.

Note that pre-patch caches might need to be manually removed and
regenerated to get the correct ABIs stored.

	[BZ #22827]
	* sysdeps/unix/sysv/linux/riscv/readelflib.c (process_elf_file): Use
	64-bit ELF type for 64-bit ELF objects.

(cherry picked from commit 6a1ff640dc)
2018-02-09 18:37:15 -05:00
Stan Shebs 2f60855711 Second try at dealing with ancient mktemp 2018-05-11 12:54:53 -07:00
Stan Shebs 58f9551f5b Defeat a malloc optimization by declaring things volatile. 2018-05-09 11:28:09 -07:00
Stan Shebs 40513af8ad Forestall optimization-out of a buffer. 2018-05-09 11:26:35 -07:00
Stan Shebs 903b7aed7c Add a clang/lld workaround for symbol not being overridden 2018-05-09 11:25:42 -07:00
Stan Shebs 090479eb8c Work around clang mishandling of assert functions in resolver buffer allocation, fixes random error returns in resolv/ tests. 2018-04-20 14:44:54 -07:00
Manuel Klimek 8254ee748c Allow suppressing the definition of __USE_FILE_OFFSET64 by defining SUPPRESS_USE_FILE_OFFSET64 in the CROSSTOOL. 2015-10-29 10:29:55 -07:00
Paul Pluzhnikov 8205f0d10e For b/5836136, do dlsym(0, "_Unwind..."), i.e. ignore libgcc_s.so.1 dlopen failure. 2014-03-03 17:03:35 -08:00
Stan Shebs 60548afc9f Define __GOOGLE_GRTE_VERSION__ 2018-03-29 14:05:07 -07:00
Stan Shebs d57236debc Add basic testsuite for dlopen_with_offset 2018-03-29 11:48:37 -07:00
Stan Shebs 641cae4c36 Add a hunk lost in merge 2018-03-28 20:31:52 -07:00
Stan Shebs 349ff1d0d5 Fix GCC compilation issues in cherrypicks 2018-03-28 19:31:45 -07:00
Paul Pluzhnikov 476f7cf2f2 For b/22641205, #include _itoa.h 2015-10-10 09:26:54 -07:00
Paul Pluzhnikov 85dc56b95f For b/20141439, don't add "foo.so" as alternate name for previously loaded "foo.so/@0x..." 2015-10-02 07:31:16 -07:00
Paul Pluzhnikov 60cdb6bb4e For b/8315591, b/20141439 correct off-by-one error that resulted in last byte of l_name being random garbage. 2015-06-03 08:58:35 -07:00
Paul Pluzhnikov cf93513721 Fix arm build by only using _itoa when building ld-linux, and not 'sln'. Also disable __google_dlopen_with_offset in fully-static link 2014-11-23 18:12:56 -08:00
Paul Pluzhnikov 6f9557ac2e For b/18243822, fix dlopen_with_offset to not reuse the same link_map entry when called on the same file with different offsets. 2014-11-10 10:56:25 -08:00
Paul Pluzhnikov 9590be9960 For Google b/8315591, experimental implementation of dlopen_with_offset. 2014-03-10 14:02:07 -07:00
Paul Pluzhnikov 8eb1716c91 Disable static linking warning for dlopen and dlmopen, and disable linking warning for sys_errlist and sys_nerr. 2014-02-28 16:51:12 -08:00
Brooks Moses 1a771e688f Backport cl/98967227 to GRTE glibc 2.19 sources. 2015-08-14 22:32:51 -07:00
Stan Shebs 31caad179b Add empty NSS borg and cache abi lists, to make testsuite work 2018-03-19 11:04:23 -07:00
Stan Shebs d5adfa3af5 Fix out-of-date bits in EXEC_ORIGIN patch 2018-03-19 09:41:11 -07:00
Brooks Moses 496eb9854c For b/12342355, remove inappropriate assert in EXEC_ORIGIN support. 2014-04-11 13:37:15 -07:00
Paul Pluzhnikov 502932b7f5 For b/4074041, add EXEC_ORIGIN support. Forward-ported from cl/56955623 and http://cl/59961863. 2014-03-08 15:12:52 -08:00
Stan Shebs 21c2ca10b1 Handle a not-found case in borg passwd lookup 2016-11-03 16:31:52 -07:00
Michael Rothwell 4e15d3291c Call the correct function. 2016-09-30 09:46:48 -07:00
Michael Rothwell f098d7ac4c Augment borg-pwd to also search through passwd.borg.base, if it exists. 2016-09-30 06:09:04 -07:00
Stan Shebs aeca36379f Describe borg-pwd better, remove dead code. 2015-08-21 14:50:53 -07:00
Max Kanat-Alexander b5861b06a6 Update nss_cache.c and nss_cache.h to current upstream version. This makes getgrgid_r and similar calls over 18x faster on corp machines. 2016-07-06 14:47:51 -07:00
Stan Shebs b06c649991 Update an include path 2018-03-14 08:17:45 -07:00
Paul Pluzhnikov eb00251677 Integrate nss_{borg,cache} local changes from glibc-2.18 to 2.19 2014-02-28 12:54:06 -08:00
Stan Shebs fc36100b27 Forward-port addition of _google_dl_debug_state_hook 2018-03-13 11:53:48 -07:00
Stan Shebs d41bed3ce0 As with gettimeofday, avoid vdso for clang-compiled time() 2018-03-13 11:37:02 -07:00
Stan Shebs 491d419cdd Forward-port addition of __google_pthread_signal_safe_key_create 2018-03-12 14:59:51 -07:00
Stan Shebs f2d31c80d6 Add a Google-only workaround for an ancient mktemp 2018-03-07 07:46:50 -08:00
Stan Shebs a4c60a19bc Bypass gettimeofday ifunc if using clang 2018-03-02 08:39:57 -08:00
Stan Shebs eb3215d3bd Add workarounds for clang and lld problems 2018-02-27 11:22:13 -08:00
Stan Shebs f0c4b81ce8 Skip a test that lld cannot handle 2018-02-27 11:17:27 -08:00
Stan Shebs 9c0f7f1394 Disable non-opt error temporarily, and __sec_comment for clang 2018-02-26 13:50:53 -08:00
Stan Shebs 10388c49b2 Remove a testing hack 2018-02-20 09:13:13 -08:00
Stan Shebs 1a12397c10 Remove debugging hack 2018-02-20 09:12:01 -08:00
Stan Shebs 654fbaf1b7 Use LN_S in more places to forestall hard link creation 2018-02-14 09:44:15 -08:00
Stan Shebs 6302c3ccf8 Add a --with-lld option to choose LLVMs lld linker 2018-02-14 09:15:44 -08:00
Stan Shebs fdb03f9736 Use clang integrated assembler except when asm is output and not required to be valid 2021-08-27 15:28:23 -07:00
Stan Shebs 6614ff3213 Add workaround to get clang to accept avx-512 instructions 2018-02-07 12:57:16 -08:00
Stan Shebs edeaa90058 Work around clang assembler error with bnd by itself on a line 2018-02-07 12:55:59 -08:00
Stan Shebs 18417626b7 Work around clang assembler error with movzx 2018-02-07 12:54:57 -08:00
Stan Shebs 85450bb67a Work around clang assembler bug with expressions in .if 2018-02-07 12:53:40 -08:00
Stan Shebs bf806c9c4e Work around lack of .tfloat in clang assembler 2018-02-06 15:53:53 -08:00
Stan Shebs 3235a02111 Put CMPLX* macros under ISO C11 2018-01-24 12:49:39 -08:00
Stan Shebs 47826951cf Add clang and debug support to conformance scripts 2018-01-24 12:42:41 -08:00
Stan Shebs 6b6086fea8 Comment out debugging hack that pollutes namespace 2018-01-24 11:32:36 -08:00
Stan Shebs 34cb52c02f Do not pass unhandled flag to clang 2018-01-23 12:53:28 -08:00
Stan Shebs dfb17f123a Add workarounds for incomplete float128 support in clang 2018-01-23 09:41:49 -08:00
Stan Shebs becb228b43 clang requires -mno-see for 387 math 2018-01-23 09:40:20 -08:00
Stan Shebs 3f1c409c0a Work around a weird clang link failure 2018-01-23 09:37:55 -08:00
Stan Shebs 2224a3d98d For now, disable asm definitions of mempcpy and strpcpy 2018-01-23 09:36:14 -08:00
Stan Shebs fe9f4b71d6 Make zero volatile to defeat constant-folding of 0.0/0.0 2018-01-23 08:28:31 -08:00
Stan Shebs 96d0e6f1e0 Reduce an error to warning if clang 2018-01-23 08:26:39 -08:00
Stan Shebs 5ac413c4fd Work around a clang bug 2018-01-23 08:25:33 -08:00
Stan Shebs 066e928543 Add clang versions of CMPLX* macros 2018-01-22 16:44:05 -08:00
Stan Shebs 85d7a988c6 Suppress tgmath3 tests if clang 2018-01-22 13:04:00 -08:00
Stan Shebs bc79ff3412 Add clang placeholders for va_arg_pack 2018-01-22 12:30:55 -08:00
Stan Shebs ce1670f0a9 Add hidden protos ahead of uses 2018-01-22 12:17:30 -08:00
Stan Shebs 3119277963 Stub out execstack problem 2018-01-22 12:12:51 -08:00
Stan Shebs a61a3a2f64 Stub out execstack, multidir, and ifunc problems 2021-08-27 15:32:35 -07:00
Stan Shebs d555ce07f4 Add --with-clang and --disable-float128 options to toplevel configury 2018-01-19 12:41:15 -08:00
Stan Shebs f555d1a9b7 Disallow extern inline if clang 2018-01-19 12:25:34 -08:00
Stan Shebs c9a3019796 Add clang version of __hidden_proto 2018-01-19 12:23:55 -08:00
Stan Shebs 1f3a3e1742 Skip undefined va_arg_pack 2018-01-19 09:31:04 -08:00
Stan Shebs 5a8bc50ed9 De-nest test-ffs.c 2018-01-19 09:22:56 -08:00
Stan Shebs d01cba7dd1 De-nest makedb.c 2018-01-19 09:21:48 -08:00
Stan Shebs cd0a44fe16 De-nest regcomp.c, suppress GCC warnings about it 2018-01-19 09:20:48 -08:00
Stan Shebs 22bef64863 Un-nest nested functions in dynamic linker 2018-01-18 15:18:30 -08:00
Stan Shebs e08a64e708 Skip execstack test, depends on nested function 2018-01-18 15:17:13 -08:00
Igor Gnatenko 56170e064e Linux: use reserved name __key in pkey_get [BZ #22797]
_key is not reserved name and we should avoid using that. It seems that
it was simple typo when pkey_* was implemented.

(cherry picked from commit 388ff7bd0d)
2018-02-07 13:53:10 +01:00
H.J. Lu 00c5a2d77a Add a missing ChangeLog item in commit 371b220f62
(cherry picked from commit 658050164d)
2018-02-06 03:07:55 -08:00
Dmitry V. Levin c8ad6ac1d1 NEWS: add an entry for bug 22638 2018-02-06 09:31:30 +00:00
H.J. Lu ce8a6550fa sparc: Check PIC instead of SHARED in start.S [BZ #22638]
Since start.o may be compiled as PIC, we should check PIC instead of
SHARED.

	[BZ #22638]
	* sysdeps/sparc/sparc32/start.S (_start): Check PIC instead of
	SHARED.
	* sysdeps/sparc/sparc64/start.S (_start): Likewise.

(cherry picked from commit 371b220f62)
2018-02-06 09:31:30 +00:00
Florian Weimer bdac1623cc Record CVE-2018-6551 in NEWS and ChangeLog [BZ #22774]
(cherry picked from commit 71aa429b02)
2018-02-06 09:21:00 +01:00
564 changed files with 104628 additions and 8478 deletions
+408
View File
@@ -1,3 +1,409 @@
2019-01-21 Florian Weimer <fweimer@redhat.com>
[BZ #20018]
CVE-2016-10739
resolv: Reject trailing characters in host names
* include/arpa/inet.h (__inet_aton_exact): Declare.
(inet_aton): Remove hidden prototype. No longer used internally.
* nscd/gai.c (__inet_aton): Do not define.
* nscd/gethstbynm3_r.c (__inet_aton): Likewise.
* nss/digits_dots.c (__inet_aton): Likewise.
(__nss_hostname_digits_dots_context): Call __inet_aton_exact.
* resolv/Makefile (tests-internal): Add tst-inet_aton_exact.
(tests): Add tst-resolv-nondecimal, tst-resolv-trailing.
(tst-resolv-nondecimal): Link with libresolv.so and libpthread.
(tst-resolv-trailing): Likewise.
* resolv/Versions (GLIBC_PRIVATE): Export __inet_aton_exact from
libc.
* resolv/inet_addr.c (inet_aton_end): Remame from __inet_aton.
Make static. Add endp parameter.
(__inet_aton_exact): New function.
(__inet_aton_ignore_trailing): New function, aliased to inet_aton.
(__inet_addr): Call inet_aton_end.
* resolv/res_init.c (res_vinit_1): Truncate nameserver for IPv4,
not just IPv6. Call __inet_aton_exact.
* resolv/tst-aton.c: Switch to <support/test-driver.c>.
(tests): Make const. Add additional test cases with trailing
characters.
(do_test): Use array_length.
* resolv/tst-inet_aton_exact.c: New file.
* resolv/tst-resolv-trailing.c: Likewise.
* resolv/tst-resolv-nondecimal.c: Likewise.
* sysdeps/posix/getaddrinfo.c (gaih_inet): Call __inet_aton_exact.
2018-11-27 Florian Weimer <fweimer@redhat.com>
[BZ #23927]
CVE-2018-19591
* sysdeps/unix/sysv/linux/if_index.c (__if_nametoindex): Avoid
descriptor leak in case of ENODEV error.
2018-05-18 Joseph Myers <joseph@codesourcery.com>
[BZ #22639]
* time/tzset.c (SECSPERDAY): Cast to time_t.
* time/tst-y2039.c: New file.
* time/Makefile (tests): Add tst-y2039.
2018-02-12 Zack Weinberg <zackw@panix.com>
[BZ #19239]
* posix/sys/types.h: Don't include sys/sysmacros.h.
* misc/sys/sysmacros.h: Remove the conditional deprecation
warnings for the macros defined by this header.
2018-05-23 H.J. Lu <hongjiu.lu@intel.com>
[BZ #23196]
* string/test-memcpy.c (do_test1): New function.
(test_main): Call it.
2018-05-23 Andreas Schwab <schwab@suse.de>
[BZ #23196]
CVE-2018-11237
* sysdeps/x86_64/multiarch/memmove-avx512-no-vzeroupper.S
(L(preloop_large)): Save initial destination pointer in %r11 and
use it instead of %rax after the loop.
* string/test-mempcpy.c (MIN_PAGE_SIZE): Define.
2018-05-11 Florian Weimer <fweimer@redhat.com>
[BZ #23166]
* include/rpc/clnt.h (rpc_createerr): Declare hidden alias.
* include/rpc/svc.h (svc_pollfd, svc_max_pollfd, svc_fdset):
Likewise.
* sunrpc/rpc_common.c (svc_fdset, rpc_createerr, svc_pollfd)
(svc_max_pollfd): Add nocommon attribute and hidden alias. Do not
export without --enable-obsolete-rpc.
* sunrpc/svcauth_des.c (svcauthdes_stats): Turn into compatibility
symbol. This should not have been exported, ever.
2018-05-11 Rafal Luzynski <digitalfreak@lingonborough.com>
[BZ #23152]
* localedata/locales/gd_GB (abmon): Fix typo in May:
"Mhàrt" -> "Cèit". Adjust the comment according to the change.
2018-05-09 Paul Pluzhnikov <ppluzhnikov@google.com>
[BZ #22786]
CVE-2018-11236
* stdlib/canonicalize.c (__realpath): Fix overflow in path length
computation.
* stdlib/Makefile (test-bz22786): New test.
* stdlib/test-bz22786.c: New test.
2018-05-05 Paul Pluzhnikov <ppluzhnikov@google.com>
[BZ #20419]
* elf/dl-load.c (open_verify): Fix stack overflow.
* elf/Makefile (tst-big-note): New test.
* elf/tst-big-note-lib.S: New.
* elf/tst-big-note.c: New.
2018-05-04 Stefan Liebler <stli@linux.vnet.ibm.com>
[BZ #23137]
* sysdeps/nptl/lowlevellock.h (lll_wait_tid):
Use atomic_load_acquire to load __tid.
2018-04-24 Joseph Myers <joseph@codesourcery.com>
* sysdeps/unix/sysv/linux/sys/ptrace.h
(PTRACE_SECCOMP_GET_METADATA): New enum value and macro.
* sysdeps/unix/sysv/linux/bits/ptrace-shared.h
(struct __ptrace_seccomp_metadata): New type.
* sysdeps/unix/sysv/linux/aarch64/sys/ptrace.h
(PTRACE_SECCOMP_GET_METADATA): Likewise.
* sysdeps/unix/sysv/linux/arm/sys/ptrace.h
(PTRACE_SECCOMP_GET_METADATA): Likewise.
* sysdeps/unix/sysv/linux/ia64/sys/ptrace.h
(PTRACE_SECCOMP_GET_METADATA): Likewise.
* sysdeps/unix/sysv/linux/powerpc/sys/ptrace.h
(PTRACE_SECCOMP_GET_METADATA): Likewise.
* sysdeps/unix/sysv/linux/s390/sys/ptrace.h
(PTRACE_SECCOMP_GET_METADATA): Likewise.
* sysdeps/unix/sysv/linux/sparc/sys/ptrace.h
(PTRACE_SECCOMP_GET_METADATA): Likewise.
* sysdeps/unix/sysv/linux/tile/sys/ptrace.h
(PTRACE_SECCOMP_GET_METADATA): Likewise.
* sysdeps/unix/sysv/linux/x86/sys/ptrace.h
(PTRACE_SECCOMP_GET_METADATA): Likewise.
2018-04-09 Florian Weimer <fweimer@redhat.com>
[BZ #23037]
* resolv/res_send.c (send_dg): Use designated initializers instead
of assignment to zero-initialize other fields of struct mmsghdr.
2018-04-06 Andreas Schwab <schwab@linux-m68k.org>
* manual/charset.texi (Converting a Character): Fix typo.
2018-04-05 Florian Weimer <fweimer@redhat.com>
* manual/examples/mbstouwcs.c (mbstouwcs): Fix loop termination,
integer overflow, memory leak on error, and indeterminate errno
value. Add a null wide character to terminate the result string.
* manual/charset.texi (Converting a Character): Mention embedded
null bytes in the mbrtowc input string. Explain what happens in
the -2 result case. Do not claim that mbrtowc is simple or
obvious to use. Adjust the description of the code example. Use
@code, not @var, for concrete variables.
2018-04-05 Florian Weimer <fweimer@redhat.com>
* manual/examples/mbstouwcs.c: New file.
* manual/charset.texi (Converting a Character): Include it.
2018-04-03 H.J. Lu <hongjiu.lu@intel.com>
[BZ #22947]
* bits/uio-ext.h (RWF_APPEND): New.
* sysdeps/unix/sysv/linux/bits/uio-ext.h (RWF_APPEND): Likewise.
* manual/llio.texi: Document RWF_APPEND.
* misc/tst-preadvwritev2-common.c (RWF_APPEND): New.
(RWF_SUPPORTED): Add RWF_APPEND.
2018-03-27 Jesse Hathaway <jesse@mbuki-mvuki.org>
* sysdeps/unix/sysv/linux/getlogin_r.c (__getlogin_r_loginuid): Return
early when linux sentinel value is set.
2018-03-27 Andreas Schwab <schwab@suse.de>
[BZ #23005]
* resolv/res_send.c (__res_context_send): Return ENOMEM if
allocation of private copy of nsaddr_list fails.
2018-03-20 Joseph Myers <joseph@codesourcery.com>
[BZ #17343]
* stdlib/random_r.c (__random_r): Use unsigned arithmetic for
possibly overflowing computations.
2018-04-26 Aurelien Jarno <aurelien@aurel32.net>
* signal/tst-sigaction.c: New file to test BZ #23069.
* signal/Makefile (tests): Fix indentation. Add tst-sigaction.
2018-04-28 Aurelien Jarno <aurelien@aurel32.net>
[BZ #23069]
* sysdeps/unix/sysv/linux/riscv/kernel_sigaction.h: New file.
2018-03-29 Florian Weimer <fweimer@redhat.com>
* sysdeps/unix/sysv/linux/i386/tst-bz21269.c (do_test): Also
capture SIGBUS.
2018-03-23 Andrew Senkevich <andrew.senkevich@intel.com>
Max Horn <max@quendi.de>
[BZ #22644]
CVE-2017-18269
* sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S: Fixed
branch conditions.
* string/test-memmove.c (do_test2): New testcase.
2018-02-22 Andrew Waterman <andrew@sifive.com>
[BZ # 22884]
* sysdeps/riscv/rvd/s_fmax.c (__fmax): Handle sNaNs correctly.
* sysdeps/riscv/rvd/s_fmin.c (__fmin): Likewise.
* sysdeps/riscv/rvf/s_fmaxf.c (__fmaxf): Likewise.
* sysdeps/riscv/rvf/s_fminf.c (__fminf): Likewise.
2018-02-22 DJ Delorie <dj@delorie.com>
* sysdeps/riscv/tls-macros.h: Do not initialize $gp.
2018-03-16 Rafal Luzynski <digitalfreak@lingonborough.com>
[BZ #22963]
* localedata/locales/cs_CZ (mon): Rename to...
(alt_mon): This.
(mon): Import from CLDR (genitive case).
2018-03-16 Rafal Luzynski <digitalfreak@lingonborough.com>
[BZ #22937]
* localedata/locales/el_CY (abmon): Rename to...
(ab_alt_mon): This.
(abmon): Import from CLDR (abbreviated genitive case).
* localedata/locales/el_GR (abmon): Rename to...
(ab_alt_mon): This.
(abmon): Import from CLDR (abbreviated genitive case).
2018-03-16 Rafal Luzynski <digitalfreak@lingonborough.com>
[BZ #22932]
* localedata/locales/lt_LT (abmon): Synchronize with CLDR.
2018-03-16 Robert Buj <robert.buj@gmail.com>
[BZ #22848]
* localedata/locales/ca_ES (abmon): Rename to...
(ab_alt_mon): This, then synchronize with CLDR (nominative case).
(mon): Rename to...
(alt_mon): This.
(abmon): Import from CLDR (genitive case, month names preceded by
"de" or "d").
(mon): Likewise.
(abday): Synchronize with CLDR.
(d_t_fmt): Likewise.
(d_fmt): Likewise.
(am_pm): Likewise.
(LC_TIME): Improve indentation.
(LC_TELEPHONE): Likewise.
(LC_NAME): Likewise.
(LC_ADDRESS): Likewise.
2018-03-12 Dmitry V. Levin <ldv@altlinux.org>
* po/pt_BR.po: Update translations.
2018-03-03 Adhemerval Zanella <adhemerval.zanella@linaro.org>
[BZ #21269]
* sysdeps/unix/sysv/linux/i386/Makefile (tests): Add tst-bz21269.
* sysdeps/unix/sysv/linux/i386/sigaction.c (SET_SA_RESTORER): Clear
sa_restorer for vDSO case.
* sysdeps/unix/sysv/linux/i386/tst-bz21269.c: New file.
2018-03-03 Andreas Schwab <schwab@linux-m68k.org>
[BZ #22918]
* nss/nsswitch.h (DEFINE_DATABASE): Don't define __nss_*_database.
* nss/nsswitch.c (DEFINE_DATABASE): Define __nss_*_database here.
* nscd/gai.c (__nss_hosts_database): Readd definition.
* posix/tst-rfc3484.c (__nss_hosts_database): Likewise.
* posix/tst-rfc3484-3.c (__nss_hosts_database): Likewise.
* posix/tst-rfc3484-2.c (__nss_hosts_database): Likewise.
2018-03-01 DJ Delorie <dj@delorie.com>
[BZ #22342]
* nscd/netgroupcache.c (addinnetgrX): Include trailing NUL in
key value.
2018-02-26 Dmitry V. Levin <ldv@altlinux.org>
[BZ #22433]
[BZ #22807]
* sysdeps/unix/sysv/linux/powerpc/sys/ptrace.h (__ptrace_request): Add
PTRACE_GETREGS, PTRACE_SETREGS, PTRACE_GETFPREGS, PTRACE_SETFPREGS,
PTRACE_GETVRREGS, PTRACE_SETVRREGS, PTRACE_GETEVRREGS,
PTRACE_SETEVRREGS, PTRACE_GETREGS64, PTRACE_SETREGS64,
PTRACE_GET_DEBUGREG, PTRACE_SET_DEBUGREG, PTRACE_GETVSRREGS,
PTRACE_SETVSRREGS, and PTRACE_SINGLEBLOCK.
2018-02-26 Tulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>
* sysdeps/unix/sysv/linux/powerpc/sys/ptrace.h: Undefine Linux
macros used in __ptrace_request.
2018-02-21 Mike FABIAN <mfabian@redhat.com>
[BZ #22517]
* localedata/locales/et_EE (LC_COLLATE): add missing “reorder-end”
2018-02-21 Rical Jasan <ricaljasan@pacific.net>
* io/fcntl.h: Fix a typo in a comment.
2018-02-20 Rical Jasan <ricaljasan@pacific.net>
* manual/creature.texi (_ISOC99_SOURCE): Update the dated
description.
[BZ #16335]
* manual/creature.texi (_POSIX_C_SOURCE): Document special values
of 199606L, 200112L, and 200809L.
(_XOPEN_SOURCE): Document special values of 600 and 700.
(_ISOC11_SOURCE): Document macro.
(_ATFILE_SOURCE): Likewise.
(_FORTIFY_SOURCE): Likewise.
2018-03-09 Aurelien Jarno <aurelien@aurel32.net>
[BZ #22919]
* sysdeps/unix/sysv/linux/sparc/sparc32/setcontext.S (__startcontext):
Add nop before __startcontext, add explaining comments.
2018-03-07 Adhemerval Zanella <adhemerval.zanella@linaro.org>
[BZ #22926]
* sysdeps/powerpc/powerpc32/sysdep.h (ABORT_TRANSACTION_IMPL): Define
empty for __SPE__.
* sysdeps/powerpc/sysdep.h (ABORT_TRANSACTION): Likewise.
* sysdeps/unix/sysv/linux/powerpc/elision-lock.c (__lll_lock_elision):
Do not build hardware transactional code for __SPE__.
* sysdeps/unix/sysv/linux/powerpc/elision-trylock.c
(__lll_trylock_elision): Likewise.
* sysdeps/unix/sysv/linux/powerpc/elision-unlock.c
(__lll_unlock_elision): Likewise.
2018-02-19 Rical Jasan <ricaljasan@pacific.net>
[BZ #6889]
* manual/filesys.texi (get_current_dir_name): Clarify behaviour.
2018-02-16 Rical Jasan <ricaljasan@pacific.net>
* manual/platform.texi (__riscv_flush_icache): Fix @deftypefun
syntax.
2018-02-09 Rical Jasan <ricaljasan@pacific.net>
* manual/creature.texi: Convert references to gcc.info to gcc.
* manual/stdio.texi: Likewise.
* manual/string.texi: Likewise.
2018-02-18 Aurelien Jarno <aurelien@aurel32.net>
[BZ #22818]
* posix/tst-glob_lstat_compat.c [__alpha__] (glob): Access
the GLIBC_2.1 version.
2018-02-02 Sean McKean <smckean83@gmail.com>
[BZ #22735]
* time/time.h (clock): Reference CLOCKS_PER_SEC in comment.
2018-02-10 Dmitry V. Levin <ldv@altlinux.org>
[BZ #22433]
* sysdeps/unix/sysv/linux/aarch64/sys/ptrace.h (__ptrace_request):
Remove arm-specific PTRACE_GET_THREAD_AREA, PTRACE_GETHBPREGS,
and PTRACE_SETHBPREGS.
2018-02-14 Adhemerval Zanella <adhemerval.zanella@linaro.org>
* sysdeps/sh/libm-test-ulps: Update.
2018-02-09 DJ Delorie <dj@redhat.com>
[BZ #22827]
* sysdeps/unix/sysv/linux/riscv/readelflib.c (process_elf_file): Use
64-bit ELF type for 64-bit ELF objects.
2018-02-07 Igor Gnatenko <ignatenko@redhat.com>
[BZ #22797]
* sysdeps/unix/sysv/linux/bits/mman-shared.h (pkey_get): Add
missing second underscore to parameter name.
2018-02-05 H.J. Lu <hongjiu.lu@intel.com>
[BZ #22638]
* sysdeps/sparc/sparc32/start.S (_start): Check PIC instead of
SHARED.
* sysdeps/sparc/sparc64/start.S (_start): Likewise.
2018-02-01 Dmitry V. Levin <ldv@altlinux.org>
* version.h (RELEASE): Set to "stable".
@@ -710,7 +1116,9 @@
2018-01-18 Arjun Shankar <arjun@redhat.com>
[BZ #22343]
[BZ #22774]
CVE-2018-6485
CVE-2018-6551
* malloc/malloc.c (checked_request2size): call REQUEST_OUT_OF_RANGE
after padding.
(_int_memalign): check for integer overflow before calling
+47 -1
View File
@@ -521,8 +521,13 @@ CFLAGS-printers-tests := -O0 -ggdb3 -DIS_IN_build
ifeq (yes,$(build-shared))
# These indicate whether to link using the built ld.so or the installed one.
ifeq ($(with-lld),no)
installed-rtld-LDFLAGS = -Wl,-dynamic-linker=$(rtlddir)/$(rtld-installed-name)
built-rtld-LDFLAGS = -Wl,-dynamic-linker=$(elf-objpfx)ld.so
else
installed-rtld-LDFLAGS = -Wl,-dynamic-linker,$(rtlddir)/$(rtld-installed-name)
built-rtld-LDFLAGS = -Wl,-dynamic-linker,$(elf-objpfx)ld.so
endif
ifndef rtld-LDFLAGS
rtld-LDFLAGS = $(installed-rtld-LDFLAGS)
@@ -656,20 +661,39 @@ libc.so-gnulib := -lgcc
endif
+preinit = $(addprefix $(csu-objpfx),crti.o)
+postinit = $(addprefix $(csu-objpfx),crtn.o)
ifeq ($(with-clang),yes)
# With clang, use the clang_rt.crt*.o files from the compiler-rt package
# in a LLVM_ENABLE_RUNTIMES build.
+prector = `$(CC) $(sysdep-LDFLAGS) --print-file-name=clang_rt.crtbegin.o`
+postctor = `$(CC) $(sysdep-LDFLAGS) --print-file-name=clang_rt.crtend.o`
else
+prector = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtbegin.o`
+postctor = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtend.o`
endif
# Variants of the two previous definitions for linking PIE programs.
ifeq ($(with-clang),yes)
# compiler-rt crt*.o also works for PIE.
+prectorS = $(+prector)
+postctorS = $(+postctor)
else
+prectorS = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtbeginS.o`
+postctorS = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtendS.o`
endif
# Variants of the two previous definitions for statically linking programs.
ifeq (yes,$(enable-static-pie))
# Static PIE must use PIE variants.
+prectorT = $(+prectorS)
+postctorT = $(+postctorS)
else
ifeq ($(with-clang),yes)
# compiler-rt crt*.o also works for static PIE.
+prectorT = $(+prector)
+postctorT = $(+postctor)
else
+prectorT = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtbeginT.o`
+postctorT = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtend.o`
endif
endif
csu-objpfx = $(common-objpfx)csu/
elf-objpfx = $(common-objpfx)elf/
@@ -829,7 +853,9 @@ endif
# We have to assume that glibc functions are called in any rounding
# mode and also change the rounding mode in a few functions. So,
# disable any optimization that assume default rounding mode.
ifeq ($(with-clang),no)
+math-flags = -frounding-math
endif
# We might want to compile with some stack-protection flag.
ifneq ($(stack-protector),)
@@ -895,6 +921,26 @@ ifeq "$(strip $(+cflags))" ""
+cflags := $(default_cflags)
endif # $(+cflags) == ""
# For now, manually add known-needed clang flags here.
ifeq ($(with-clang),yes)
+cflags += -fheinous-gnu-extensions
# Don't complain about __sigsetjmp.
+cflags += -Wno-builtin-requires-header
+cflags += -Wno-incomplete-setjmp-declaration
# clang takes gnu89 as requiring a warning about duplicates, gcc does not
+cflags += -Wno-duplicate-decl-specifier
# Non-string format arguments come from debugging prints in ld.so.
+cflags += -Wno-format-security
ifeq ($(with-lld),yes)
LDFLAGS.so += -fuse-ld=lld
LDFLAGS-rtld += -fuse-ld=lld
LDFLAGS += -fuse-ld=lld
LDFLAGS += -Wl,--undefined-version
endif
endif # with-clang == yes
+cflags += $(cflags-cpu) $(+gccwarn) $(+merge-constants) $(+math-flags) \
$(+stack-protector)
+gcc-nowarn := -w
@@ -1202,7 +1248,7 @@ all-subdirs = csu assert ctype locale intl catgets math setjmp signal \
grp pwd posix io termios resource misc socket sysvipc gmon \
gnulib iconv iconvdata wctype manual shadow gshadow po argp \
crypt localedata timezone rt conform debug mathvec support \
dlfcn elf
dlfcn elf google-nsl-stub
ifndef avoid-generated
# sysd-sorted itself will contain rules making the sysd-sorted target
+7 -14
View File
@@ -653,7 +653,7 @@ $(common-objpfx)shlib.lds: $(common-objpfx)config.make $(..)Makerules
common-generated += shlib.lds
shlib-lds = $(common-objpfx)shlib.lds
shlib-lds-flags = -T $(shlib-lds)
shlib-lds-flags = -Wl,-T,$(shlib-lds)
endif
define build-shlib
@@ -705,7 +705,7 @@ LDFLAGS-c.so = -nostdlib -nostartfiles
# But we still want to link libc.so against $(libc.so-gnulib).
LDLIBS-c.so += $(libc.so-gnulib)
# Give libc.so an entry point and make it directly runnable itself.
LDFLAGS-c.so += -e __libc_main
LDFLAGS-c.so += -Wl,-e,__libc_main
# Pre-link the objects of libc_pic.a so that we can locally resolve
# COMMON symbols before we link against ld.so. This is because ld.so
# contains some of libc_pic.a already, which will prevent the COMMONs
@@ -736,7 +736,7 @@ endif
ifeq (,$(filter sunrpc,$(subdirs)))
$(common-objpfx)linkobj/libc_pic.a: $(common-objpfx)libc_pic.a
$(make-target-directory)
ln -f $< $@
$(LN_S) -f $< $@
else
$(common-objpfx)linkobj/libc_pic.a: $(common-objpfx)libc_pic.a \
$(common-objpfx)sunrpc/librpc_compat_pic.a
@@ -1094,7 +1094,7 @@ mv -f $@.new $@
endef
define make-link-multidir
$(make-target-directory)
ln -f $(objpfx)/$(@F) $@
$(LN_S) -f $(objpfx)/$(@F) $@
endef
endif
@@ -1133,20 +1133,13 @@ install: $(inst_slibdir)/libc.so$(libc.so-version)
# for the configuration we are building. We put this statement into
# the linker scripts we install for -lc et al so that they will not be
# used by a link for a different format on a multi-architecture system.
$(common-objpfx)format.lds: $(..)scripts/output-format.sed \
$(common-objpfx)config.make \
$(common-objpfx)format.lds: $(common-objpfx)config.make \
$(common-objpfx)config.h $(..)Makerules
ifneq (unknown,$(output-format))
echo > $@.new 'OUTPUT_FORMAT($(output-format))'
else
$(LINK.o) -shared $(sysdep-LDFLAGS) $(rtld-LDFLAGS) \
$(LDFLAGS.so) $(LDFLAGS-lib.so) \
-x c /dev/null -o $@.so -Wl,--verbose -v 2>&1 \
| sed -n -f $< > $@.new
test -s $@.new
-x c /dev/null -o $@.so 2>/dev/null
$(OBJDUMP) -f $@.so | sed -n 's/.*file format \(.*\)/OUTPUT_FORMAT(\1)/;T;p' > $@
rm -f $@.so
endif
mv -f $@.new $@
common-generated += format.lds
ifndef subdir
+90
View File
@@ -4,6 +4,92 @@ See the end for copying conditions.
Please send GNU C library bug reports via <https://sourceware.org/bugzilla/>
using `glibc' in the "product" field.
Version 2.27.1
Major new features:
* Nominative and genitive month names are now supported for the Catalan and
Czech languages. The Catalan and Greek languages now support abbreviated
alternative month names.
Deprecated and removed features, and other changes affecting compatibility:
* The macros 'major', 'minor', and 'makedev' are now only available from
the header <sys/sysmacros.h>; not from <sys/types.h> or various other
headers that happen to include <sys/types.h>. These macros are rarely
used, not part of POSIX nor XSI, and their names frequently collide with
user code; see https://sourceware.org/bugzilla/show_bug.cgi?id=19239 for
further explanation.
<sys/sysmacros.h> is a GNU extension. Portable programs that require
these macros should first include <sys/types.h>, and then include
<sys/sysmacros.h> if __GNU_LIBRARY__ is defined.
Security related changes:
CVE-2021-3999: Passing a buffer of size exactly 1 byte to the getcwd
function may result in an off-by-one buffer underflow and overflow
when the current working directory is longer than PATH_MAX and also
corresponds to the / directory through an unprivileged mount
namespace. Reported by Qualys.
CVE-2016-10739: The getaddrinfo function could successfully parse IPv4
addresses with arbitrary trailing characters, potentially leading to data
or command injection issues in applications.
CVE-2018-19591: A file descriptor leak in if_nametoindex can lead to a
denial of service due to resource exhaustion when processing getaddrinfo
calls with crafted host names. Reported by Guido Vranken.
CVE-2017-18269: An SSE2-based memmove implementation for the i386
architecture could corrupt memory. Reported by Max Horn.
CVE-2018-11236: Very long pathname arguments to realpath function could
result in an integer overflow and buffer overflow. Reported by Alexey
Izbyshev.
CVE-2018-11237: The mempcpy implementation for the Intel Xeon Phi
architecture could write beyond the target buffer, resulting in a buffer
overflow. Reported by Andreas Schwab.
The following bugs are resolved with this release:
[6889] 'PWD' mentioned but not specified
[16335] Feature test macro documentation incomplete and out of date
[17343] Signed integer overflow in /stdlib/random_r.c
[20419] files with large allocated notes crash in open_verify
[21269] i386 sigaction sa_restorer handling is wrong
[22342] NSCD not properly caching netgroup
[22638] sparc: static binaries are broken if glibc is built by gcc
configured with --enable-default-pie
[22644] memmove-sse2-unaligned on 32bit x86 produces garbage when crossing
2GB threshold
[22735] Misleading typo in time.h source comment regarding CLOCKS_PER_SECOND
[22786] Stack buffer overflow in realpath() if input size is close
to SSIZE_MAX
[22797] Linux: use reserved name __key in pkey_get
[22807] PTRACE_* constants missing for powerpc
[22818] posix/tst-glob_lstat_compat failure on alpha
[22827] RISC-V ELF64 parser mis-reads flag in ldconfig
[22848] ca_ES: update date definitions from CLDR
[22884] RISCV fmax/fmin handle signalling NANs incorrectly
[22918] multiple common of `__nss_shadow_database'
[22919] sparc32: backtrace yields infinite backtrace with makecontext
[22926] FTBFS on powerpcspe
[22932] lt_LT: Update of abbreviated month names from CLDR required
[22937] Greek (el_GR, el_CY) locales actually need ab_alt_mon
[22947] FAIL: misc/tst-preadvwritev2
[22963] cs_CZ: Add alternative month names
[23005] Crash in __res_context_send after memory allocation failure
[23037] initialize msg_flags to zero for sendmmsg() calls
[23069] sigaction broken on riscv64-linux-gnu
[23137] s390: pthread_join sometimes block indefinitely (on 31bit and libc
build with -Os)
[23152] gd_GB: Fix typo in "May" (abbreviated)
[23166] sunrpc: Remove stray exports without --enable-obsolete-rpc
[23196] __mempcpy_avx512_no_vzeroupper mishandles large copies
Version 2.27
@@ -262,6 +348,10 @@ Security related changes:
an object size near the value of SIZE_MAX, would return a pointer to a
buffer which is too small, instead of NULL. Reported by Jakub Wilk.
CVE-2018-6551: The malloc function, when called with an object size near
the value of SIZE_MAX, would return a pointer to a buffer which is too
small, instead of NULL.
The following bugs are resolved with this release:
[866] glob: glob should match dangling symlinks
+61
View File
@@ -0,0 +1,61 @@
This file documents Google's modified version of glibc, known as GRTE
(Google Run Time Environment). GRTE serves as the common C library for
internal Google applications running on production systems.
While GRTE is nearly identical to stock glibc, it does have a number
of local changes. These run the gamut from patches that were
submitted but not accepted for trunk glibc, to workarounds for quirks
of Google infrastructure, to extensions that are critical for the
proper functioning of applications. The ideal, however, is to have no
local changes at all.
GRTE versions are identified by a small integer, which generally
corresponds to a particular glibc version. GRTE v4 is based on
glibc-2.19, while GRTE v5 is based on glibc-2.27, for instance.
BUILDING GRTE WITH GCC
When using GCC, GRTE v4 and later will build with native
configure/make in the usual way for glibc. For v4, nscd does not
work, so add --disable-nscd when configuring.
Supported architectures include x86_64 and ppc64le.
Testsuites will likely have some additional failures.
BUILDING GRTE WITH CLANG
GRTE v5 and later can also be built with clang and (optionally) lld.
LLVM support for GNU source code continues to evolve (as of June
2018), so the process is less straightforward, and likely to change
from what is documented here. There are a number of glibc patches
that make this work, including additional configure options mentioned
below.
The minimum version of clang is 6.0.0. If lld is to be used for linking,
it needs to be newer than 6.0.0.
Configure:
CC=path-to-llvm/clang CXX=path-to-llvm/clang++ \
../glibc/configure --disable-werror --with-clang --disable-float128 \
--with-lld --with-default-link --disable-multi-arch --prefix=/something
To build with BFD ld as linker, omit the "--with-lld
--with-default-link". (Gold has had problems in the past.)
Build:
make
make install
Test:
make check
Testsuite results will show many unexpected failures beyond the
GCC-compiled results; about 390 for x86-64. These are a combination
of known bugs in clang, and issues with conformance to old standards
predating clang. Note that the clang build still needs symlinks to
libgcc and libstdc++ in the installed library directory, so that
thread cancellation tests pass.
Vendored
+8 -11
View File
@@ -223,20 +223,17 @@ AC_DEFUN([LIBC_LINKER_FEATURE],
[AC_MSG_CHECKING([for linker that supports $1])
libc_linker_feature=no
if test x"$gnu_ld" = x"yes"; then
libc_linker_check=`$LD -v --help 2>/dev/null | grep "\$1"`
if test -n "$libc_linker_check"; then
cat > conftest.c <<EOF
cat > conftest.c <<EOF
int _start (void) { return 42; }
EOF
if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp
$2 -nostdlib -nostartfiles
-fPIC -shared -o conftest.so conftest.c
1>&AS_MESSAGE_LOG_FD])
then
libc_linker_feature=yes
fi
rm -f conftest*
if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp
$2 -nostdlib -nostartfiles
-fPIC -shared -o conftest.so conftest.c
1>&AS_MESSAGE_LOG_FD])
then
libc_linker_feature=yes
fi
rm -f conftest*
fi
if test $libc_linker_feature = yes; then
$3
+12 -1
View File
@@ -86,10 +86,21 @@ __END_DECLS
parentheses around EXPR. Otherwise, those added parentheses would
suppress warnings we'd expect to be detected by gcc's -Wparentheses. */
# if defined __cplusplus
# if defined __has_builtin
# if __has_builtin (__builtin_FILE)
# define __ASSERT_FILE __builtin_FILE ()
# define __ASSERT_LINE __builtin_LINE ()
# endif
# endif
# if !defined __ASSERT_FILE
# define __ASSERT_FILE __FILE__
# define __ASSERT_LINE __LINE__
# endif
# define assert(expr) \
(static_cast <bool> (expr) \
? void (0) \
: __assert_fail (#expr, __FILE__, __LINE__, __ASSERT_FUNCTION))
: __assert_fail (#expr, __ASSERT_FILE, __ASSERT_LINE, \
__ASSERT_FUNCTION))
# elif !defined __GNUC__ || defined __STRICT_ANSI__
# define assert(expr) \
((expr) \
@@ -9450,7 +9450,6 @@ move-if-change
check-execstack.awk
pylint
pylintrc
output-format.sed
merge-test-results.sh
update-copyrights
config-uname.sh
+1
View File
@@ -28,5 +28,6 @@
#define RWF_DSYNC 0x00000002 /* per-IO O_DSYNC. */
#define RWF_SYNC 0x00000004 /* per-IO O_SYNC. */
#define RWF_NOWAIT 0x00000008 /* per-IO nonblocking mode. */
#define RWF_APPEND 0x00000010 /* per-IO O_APPEND. */
#endif /* sys/uio_ext.h */
+4 -2
View File
@@ -171,8 +171,10 @@
/* Define if gcc supports attribute ifunc. */
#undef HAVE_GCC_IFUNC
/* Define if the linker defines __ehdr_start. */
#undef HAVE_EHDR_START
/* Define if CC supports attribute retain. */
#undef HAVE_GNU_RETAIN
#define WANT_FLOAT128 0
/*
*/
+1 -1
View File
@@ -72,7 +72,6 @@ fno-unit-at-a-time = @fno_unit_at_a_time@
bind-now = @bindnow@
have-hash-style = @libc_cv_hashstyle@
use-default-link = @use_default_link@
output-format = @libc_cv_output_format@
have-cxx-thread_local = @libc_cv_cxx_thread_local@
have-loop-to-function = @libc_cv_cc_loop_to_function@
@@ -101,6 +100,7 @@ use-nscd = @use_nscd@
build-hardcoded-path-in-tests= @hardcoded_path_in_tests@
build-pt-chown = @build_pt_chown@
have-tunables = @have_tunables@
enable-float128 = @enable_float128@
# Build tools.
CC = @CC@
Vendored
+144 -77
View File
@@ -623,7 +623,6 @@ libc_cv_cc_submachine
libc_cv_cc_nofma
libc_cv_mtls_dialect_gnu2
fno_unit_at_a_time
libc_cv_output_format
libc_cv_has_glob_dat
libc_cv_hashstyle
libc_cv_fpie
@@ -669,6 +668,7 @@ stack_protector
libc_cv_ssp
libc_cv_with_fp
base_machine
enable_float128
have_tunables
build_pt_chown
build_nscd
@@ -759,6 +759,8 @@ with_gd_include
with_gd_lib
with_binutils
with_selinux
with_clang
with_lld
with_headers
with_default_link
enable_sanity_checks
@@ -787,6 +789,7 @@ enable_build_nscd
enable_nscd
enable_pt_chown
enable_tunables
enable_float128
enable_mathvec
with_cpu
'
@@ -1459,6 +1462,7 @@ Optional Features:
--enable-pt_chown Enable building and installing pt_chown
--enable-tunables Enable tunables support. Known values are 'yes',
'no' and 'valstring'
--disable-float128 disable float128 support
--enable-mathvec Enable building and installing mathvec [default
depends on architecture]
@@ -1472,6 +1476,8 @@ Optional Packages:
--with-gd-lib=DIR find libgd library files in DIR
--with-binutils=PATH specify location of binutils (as and ld)
--with-selinux if building with SELinux support
--with-clang if building with clang (temporary)
--with-lld if building/linking with lld (temporary)
--with-headers=PATH location of system headers to use (for example
/usr/src/linux/include) [default=compiler default]
--with-default-link do not use explicit linker scripts
@@ -3312,6 +3318,26 @@ else
fi
# Check whether --with-clang was given.
if test "${with_clang+set}" = set; then :
withval=$with_clang; with_clang=$withval
else
with_clang=no
fi
config_vars="$config_vars
with-clang = $with_clang"
# Check whether --with-lld was given.
if test "${with_lld+set}" = set; then :
withval=$with_lld; with_lld=$withval
else
with_lld=no
fi
config_vars="$config_vars
with-lld = $with_lld"
# Check whether --with-headers was given.
if test "${with_headers+set}" = set; then :
@@ -3721,6 +3747,19 @@ if test "$have_tunables" = yes; then
fi
# Check whether --enable-float128 was given.
if test "${enable_float128+set}" = set; then :
enableval=$enable_float128; enable_float128=$enableval
else
enable_float128=yes
fi
if test "$enable_float128" = yes; then
$as_echo "#define WANT_FLOAT128 1" >>confdefs.h
fi
# The abi-tags file uses a fairly simplistic model for name recognition that
# can't distinguish i486-pc-linux-gnu fully from i486-pc-gnu. So we mutate a
# $host_os of `gnu*' here to be `gnu-gnu*' just so that it can tell.
@@ -4009,6 +4048,31 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_gcc_indirect_function" >&5
$as_echo "$libc_cv_gcc_indirect_function" >&6; }
# Check if CC supports attribute retain as it is used in attribute_used_retain macro.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU attribute retain support" >&5
$as_echo_n "checking for GNU attribute retain support... " >&6; }
if ${libc_cv_gnu_retain+:} false; then :
$as_echo_n "(cached) " >&6
else
cat > conftest.c <<EOF
static int var __attribute__ ((used, retain, section ("__libc_atexit")));
EOF
libc_cv_gnu_retain=no
if ${CC-cc} -Werror -c conftest.c -o /dev/null 1>&5 \
2>&5 ; then
libc_cv_gnu_retain=yes
fi
rm -f conftest*
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_gnu_retain" >&5
$as_echo "$libc_cv_gnu_retain" >&6; }
if test $libc_cv_gnu_retain = yes; then
$as_echo "#define HAVE_GNU_RETAIN 1" >>confdefs.h
fi
config_vars="$config_vars
have-gnu-retain = $libc_cv_gnu_retain"
# Check if gcc warns about alias for function with incompatible types.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler warns about alias for function with incompatible types" >&5
$as_echo_n "checking if compiler warns about alias for function with incompatible types... " >&6; }
@@ -4438,6 +4502,7 @@ $as_echo "$libc_cv_prog_ld_gnu" >&6; }
gnu_ld=$libc_cv_prog_ld_gnu
if test "$with_clang" = no; then
# Accept binutils 2.25 or newer.
for ac_prog in $AS
do
@@ -4502,7 +4567,9 @@ if test $ac_verc_fail = yes; then
AS=: critic_missing="$critic_missing as"
fi
fi
if test "$with_lld" = no; then
if test -n "`$LD --version | sed -n 's/^GNU \(gold\).*$/\1/p'`"; then
# Accept gold 1.14 or higher
for ac_prog in $LD
@@ -4632,6 +4699,7 @@ if test $ac_verc_fail = yes; then
LD=: critic_missing="$critic_missing GNU ld"
fi
fi
fi
# These programs are version sensitive.
@@ -5030,7 +5098,9 @@ main ()
{
#if !defined __GNUC__ || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 9)
#if !defined __clang__
#error insufficient compiler
#endif
#endif
;
return 0;
@@ -5307,6 +5377,8 @@ fi
# Obtain some C++ header file paths. This is used to make a local
# copy of those headers in Makerules.
if test -n "$CXX"; then
# In theory the clang and gcc regexes can be merged, but the
# result is incomprehensible.
find_cxx_header () {
echo "#include <$1>" | $CXX -M -MP -x c++ - 2>/dev/null \
| sed -n "\,$1:,{s/:\$//;p}"
@@ -5817,17 +5889,17 @@ fi
$as_echo "$libc_linker_feature" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker that supports --no-dynamic-linker" >&5
$as_echo_n "checking for linker that supports --no-dynamic-linker... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker that supports -z start-stop-gc" >&5
$as_echo_n "checking for linker that supports -z start-stop-gc... " >&6; }
libc_linker_feature=no
if test x"$gnu_ld" = x"yes"; then
libc_linker_check=`$LD -v --help 2>/dev/null | grep "\--no-dynamic-linker"`
libc_linker_check=`$LD -v --help 2>/dev/null | grep "\-z start-stop-gc"`
if test -n "$libc_linker_check"; then
cat > conftest.c <<EOF
int _start (void) { return 42; }
EOF
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp
-Wl,--no-dynamic-linker -nostdlib -nostartfiles
-Wl,-z,start-stop-gc -nostdlib -nostartfiles
-fPIC -shared -o conftest.so conftest.c
1>&5'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
@@ -5841,6 +5913,68 @@ EOF
rm -f conftest*
fi
fi
if test $libc_linker_feature = yes; then
libc_cv_z_start_stop_gc=yes
else
libc_cv_z_start_stop_gc=no
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_linker_feature" >&5
$as_echo "$libc_linker_feature" >&6; }
config_vars="$config_vars
have-z-start-stop-gc = $libc_cv_z_start_stop_gc"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker that supports -z pack-relative-relocs" >&5
$as_echo_n "checking for linker that supports -z pack-relative-relocs... " >&6; }
libc_linker_feature=no
if test x"$gnu_ld" = x"yes"; then
cat > conftest.c <<EOF
int _start (void) { return 42; }
EOF
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp
-Wl,-z,pack-relative-relocs -nostdlib -nostartfiles
-fPIC -shared -o conftest.so conftest.c
1>&5'
{ { 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_linker_feature=yes
fi
rm -f conftest*
fi
if test $libc_linker_feature = yes; then
libc_cv_dt_relr=yes
else
libc_cv_dt_relr=no
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_linker_feature" >&5
$as_echo "$libc_linker_feature" >&6; }
config_vars="$config_vars
have-dt-relr = $libc_cv_dt_relr"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker that supports --no-dynamic-linker" >&5
$as_echo_n "checking for linker that supports --no-dynamic-linker... " >&6; }
libc_linker_feature=no
if test x"$gnu_ld" = x"yes"; then
cat > conftest.c <<EOF
int _start (void) { return 42; }
EOF
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp
-Wl,--no-dynamic-linker -nostdlib -nostartfiles
-fPIC -shared -o conftest.so conftest.c
1>&5'
{ { 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_linker_feature=yes
fi
rm -f conftest*
fi
if test $libc_linker_feature = yes; then
libc_cv_no_dynamic_linker=yes
else
@@ -6018,24 +6152,6 @@ fi
$as_echo "$libc_cv_has_glob_dat" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker output format" >&5
$as_echo_n "checking linker output format... " >&6; }
if ${libc_cv_output_format+:} false; then :
$as_echo_n "(cached) " >&6
else
if libc_cv_output_format=`
${CC-cc} -nostartfiles -nostdlib $no_ssp -Wl,--print-output-format 2>&5`
then
:
else
libc_cv_output_format=
fi
test -n "$libc_cv_output_format" || libc_cv_output_format=unknown
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_output_format" >&5
$as_echo "$libc_cv_output_format" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fno-toplevel-reorder -fno-section-anchors" >&5
$as_echo_n "checking for -fno-toplevel-reorder -fno-section-anchors... " >&6; }
if ${libc_cv_fno_toplevel_reorder+:} false; then :
@@ -6170,7 +6286,7 @@ char *foo (const char *a, const char *b)
return __builtin_strstr (a, b);
}
EOF
if { ac_try='${CC-cc} -O3 -S conftest.c -o - | grep -F "my_strstr" > /dev/null'
if { ac_try='${CC-cc} -O3 -S conftest.c -o - | grep -F "strstr" > /dev/null'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -6251,7 +6367,7 @@ __attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns")))
foo (void) {}
EOF
libc_cv_cc_loop_to_function=no
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -c conftest.c'
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -Werror -c conftest.c'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -6502,58 +6618,6 @@ if test $libc_cv_predef_fortify_source = yes; then
fi
# Some linkers on some architectures support __ehdr_start but with
# bugs. Make sure usage of it does not create relocations in the
# output (as the linker should resolve them all for us).
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker provides working __ehdr_start" >&5
$as_echo_n "checking whether the linker provides working __ehdr_start... " >&6; }
if ${libc_cv_ehdr_start+:} false; then :
$as_echo_n "(cached) " >&6
else
old_CFLAGS="$CFLAGS"
old_LDFLAGS="$LDFLAGS"
old_LIBS="$LIBS"
CFLAGS="$CFLAGS -fPIC"
LDFLAGS="$LDFLAGS -nostdlib -nostartfiles -shared $no_ssp"
LIBS=
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
typedef struct {
char foo;
long val;
} Ehdr;
extern const Ehdr __ehdr_start __attribute__ ((visibility ("hidden")));
long ehdr (void) { return __ehdr_start.val; }
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
if $READELF -r conftest | grep -F __ehdr_start >/dev/null; then
libc_cv_ehdr_start=broken
else
libc_cv_ehdr_start=yes
fi
else
libc_cv_ehdr_start=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
CFLAGS="$old_CFLAGS"
LDFLAGS="$old_LDFLAGS"
LIBS="$old_LIBS"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ehdr_start" >&5
$as_echo "$libc_cv_ehdr_start" >&6; }
if test "$libc_cv_ehdr_start" = yes; then
$as_echo "#define HAVE_EHDR_START 1" >>confdefs.h
elif test "$libc_cv_ehdr_start" = broken; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: linker is broken -- you should upgrade" >&5
$as_echo "$as_me: WARNING: linker is broken -- you should upgrade" >&2;}
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_trap with no external dependencies" >&5
$as_echo_n "checking for __builtin_trap with no external dependencies... " >&6; }
if ${libc_cv_builtin_trap+:} false; then :
@@ -6771,7 +6835,10 @@ libc_cv_pie_default=$libc_cv_cc_pie_default
# Set the `multidir' variable by grabbing the variable from the compiler.
# We do it once and save the result in a generated makefile.
libc_cv_multidir=.
if test "$with_clang" = no; then
libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
fi
if test "$static_pie" = yes; then
+65 -47
View File
@@ -137,6 +137,20 @@ AC_ARG_WITH([selinux],
[if building with SELinux support]),
[with_selinux=$withval],
[with_selinux=auto])
dnl This is a temporary hack, to help sort out wired-in GCC assumptions.
AC_ARG_WITH([clang],
AC_HELP_STRING([--with-clang],
[if building with clang (temporary)]),
[with_clang=$withval],
[with_clang=no])
LIBC_CONFIG_VAR([with-clang], [$with_clang])
dnl This is a temporary hack, to help with BFD LD vs LLD debugging.
AC_ARG_WITH([lld],
AC_HELP_STRING([--with-lld],
[if building/linking with lld (temporary)]),
[with_lld=$withval],
[with_lld=no])
LIBC_CONFIG_VAR([with-lld], [$with_lld])
AC_ARG_WITH([headers],
AC_HELP_STRING([--with-headers=PATH],
@@ -435,6 +449,16 @@ if test "$have_tunables" = yes; then
AC_DEFINE(HAVE_TUNABLES)
fi
AC_ARG_ENABLE([float128],
AC_HELP_STRING([--disable-float128],
[disable float128 support]),
[enable_float128=$enableval],
[enable_float128=yes])
AC_SUBST(enable_float128)
if test "$enable_float128" = yes; then
AC_DEFINE(WANT_FLOAT128)
fi
# The abi-tags file uses a fairly simplistic model for name recognition that
# can't distinguish i486-pc-linux-gnu fully from i486-pc-gnu. So we mutate a
# $host_os of `gnu*' here to be `gnu-gnu*' just so that it can tell.
@@ -646,6 +670,23 @@ if ${CC-cc} -c conftest.c -o conftest.o 1>&AS_MESSAGE_LOG_FD \
fi
rm -f conftest*])
# Check if CC supports attribute retain as it is used in attribute_used_retain macro.
AC_CACHE_CHECK([for GNU attribute retain support],
libc_cv_gnu_retain, [dnl
cat > conftest.c <<EOF
static int var __attribute__ ((used, retain, section ("__libc_atexit")));
EOF
libc_cv_gnu_retain=no
if ${CC-cc} -Werror -c conftest.c -o /dev/null 1>&AS_MESSAGE_LOG_FD \
2>&AS_MESSAGE_LOG_FD ; then
libc_cv_gnu_retain=yes
fi
rm -f conftest*])
if test $libc_cv_gnu_retain = yes; then
AC_DEFINE(HAVE_GNU_RETAIN)
fi
LIBC_CONFIG_VAR([have-gnu-retain], [$libc_cv_gnu_retain])
# Check if gcc warns about alias for function with incompatible types.
AC_CACHE_CHECK([if compiler warns about alias for function with incompatible types],
libc_cv_gcc_incompatible_alias, [dnl
@@ -911,12 +952,15 @@ AC_PROG_LN_S
LIBC_PROG_BINUTILS
if test "$with_clang" = no; then
# Accept binutils 2.25 or newer.
AC_CHECK_PROG_VER(AS, $AS, --version,
[GNU assembler.* \([0-9]*\.[0-9.]*\)],
[2.1[0-9][0-9]*|2.2[5-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*],
AS=: critic_missing="$critic_missing as")
fi
if test "$with_lld" = no; then
if test -n "`$LD --version | sed -n 's/^GNU \(gold\).*$/\1/p'`"; then
# Accept gold 1.14 or higher
AC_CHECK_PROG_VER(LD, $LD, --version,
@@ -929,6 +973,7 @@ else
[2.1[0-9][0-9]*|2.2[5-9]*|2.[3-9][0-9]*|[3-9].*|[1-9][0-9]*],
LD=: critic_missing="$critic_missing GNU ld")
fi
fi
# These programs are version sensitive.
AC_CHECK_TOOL_PREFIX
@@ -958,7 +1003,9 @@ AC_CHECK_PROG_VER(BISON, bison, --version,
AC_CACHE_CHECK([if $CC is sufficient to build libc], libc_cv_compiler_ok, [
AC_TRY_COMPILE([], [
#if !defined __GNUC__ || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 9)
#if !defined __clang__
#error insufficient compiler
#endif
#endif],
[libc_cv_compiler_ok=yes],
[libc_cv_compiler_ok=no])])
@@ -1037,7 +1084,10 @@ AC_SUBST(CXX_SYSINCLUDES)
# Obtain some C++ header file paths. This is used to make a local
# copy of those headers in Makerules.
changequote(,)dnl
if test -n "$CXX"; then
# In theory the clang and gcc regexes can be merged, but the
# result is incomprehensible.
find_cxx_header () {
echo "#include <$1>" | $CXX -M -MP -x c++ - 2>/dev/null \
| sed -n "\,$1:,{s/:\$//;p}"
@@ -1046,6 +1096,7 @@ if test -n "$CXX"; then
CXX_CMATH_HEADER="$(find_cxx_header cmath)"
CXX_BITS_STD_ABS_H="$(find_cxx_header bits/std_abs.h)"
fi
changequote([,])dnl
AC_SUBST(CXX_CSTDLIB_HEADER)
AC_SUBST(CXX_CMATH_HEADER)
AC_SUBST(CXX_BITS_STD_ABS_H)
@@ -1292,6 +1343,15 @@ LIBC_LINKER_FEATURE([-z execstack], [-Wl,-z,execstack],
[libc_cv_z_execstack=yes], [libc_cv_z_execstack=no])
AC_SUBST(libc_cv_z_execstack)
LIBC_LINKER_FEATURE([-z start-stop-gc], [-Wl,-z,start-stop-gc],
[libc_cv_z_start_stop_gc=yes], [libc_cv_z_start_stop_gc=no])
LIBC_CONFIG_VAR([have-z-start-stop-gc], [$libc_cv_z_start_stop_gc])
LIBC_LINKER_FEATURE([-z pack-relative-relocs],
[-Wl,-z,pack-relative-relocs],
[libc_cv_dt_relr=yes], [libc_cv_dt_relr=no])
LIBC_CONFIG_VAR([have-dt-relr], [$libc_cv_dt_relr])
LIBC_LINKER_FEATURE([--no-dynamic-linker],
[-Wl,--no-dynamic-linker],
[libc_cv_no_dynamic_linker=yes],
@@ -1403,17 +1463,6 @@ fi
rm -f conftest*])
AC_SUBST(libc_cv_has_glob_dat)
AC_CACHE_CHECK(linker output format, libc_cv_output_format, [dnl
if libc_cv_output_format=`
${CC-cc} -nostartfiles -nostdlib $no_ssp -Wl,--print-output-format 2>&AS_MESSAGE_LOG_FD`
then
:
else
libc_cv_output_format=
fi
test -n "$libc_cv_output_format" || libc_cv_output_format=unknown])
AC_SUBST(libc_cv_output_format)
AC_CACHE_CHECK(for -fno-toplevel-reorder -fno-section-anchors, libc_cv_fno_toplevel_reorder, [dnl
cat > conftest.c <<EOF
int foo;
@@ -1502,7 +1551,7 @@ char *foo (const char *a, const char *b)
}
EOF
dnl
if AC_TRY_COMMAND([${CC-cc} -O3 -S conftest.c -o - | grep -F "my_strstr" > /dev/null]);
if AC_TRY_COMMAND([${CC-cc} -O3 -S conftest.c -o - | grep -F "strstr" > /dev/null]);
then
libc_cv_gcc_builtin_redirection=yes
else
@@ -1545,7 +1594,7 @@ __attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns")))
foo (void) {}
EOF
libc_cv_cc_loop_to_function=no
if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -c conftest.c])
if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -Werror -c conftest.c])
then
libc_cv_cc_loop_to_function=yes
fi
@@ -1624,40 +1673,6 @@ if test $libc_cv_predef_fortify_source = yes; then
fi
AC_SUBST(CPPUNDEFS)
# Some linkers on some architectures support __ehdr_start but with
# bugs. Make sure usage of it does not create relocations in the
# output (as the linker should resolve them all for us).
AC_CACHE_CHECK([whether the linker provides working __ehdr_start],
libc_cv_ehdr_start, [
old_CFLAGS="$CFLAGS"
old_LDFLAGS="$LDFLAGS"
old_LIBS="$LIBS"
CFLAGS="$CFLAGS -fPIC"
LDFLAGS="$LDFLAGS -nostdlib -nostartfiles -shared $no_ssp"
LIBS=
AC_LINK_IFELSE([AC_LANG_SOURCE([
typedef struct {
char foo;
long val;
} Ehdr;
extern const Ehdr __ehdr_start __attribute__ ((visibility ("hidden")));
long ehdr (void) { return __ehdr_start.val; }
])],
[if $READELF -r conftest | grep -F __ehdr_start >/dev/null; then
libc_cv_ehdr_start=broken
else
libc_cv_ehdr_start=yes
fi], [libc_cv_ehdr_start=no])
CFLAGS="$old_CFLAGS"
LDFLAGS="$old_LDFLAGS"
LIBS="$old_LIBS"
])
if test "$libc_cv_ehdr_start" = yes; then
AC_DEFINE([HAVE_EHDR_START])
elif test "$libc_cv_ehdr_start" = broken; then
AC_MSG_WARN([linker is broken -- you should upgrade])
fi
AC_CACHE_CHECK(for __builtin_trap with no external dependencies,
libc_cv_builtin_trap, [dnl
libc_cv_builtin_trap=no
@@ -1811,7 +1826,10 @@ AC_SUBST(libc_cv_pie_default)
# Set the `multidir' variable by grabbing the variable from the compiler.
# We do it once and save the result in a generated makefile.
libc_cv_multidir=.
if test "$with_clang" = no; then
libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
fi
AC_SUBST(libc_cv_multidir)
if test "$static_pie" = yes; then
+22 -1
View File
@@ -39,20 +39,26 @@ $CFLAGS{"POSIX2008"} = "-std=c99 -D_POSIX_C_SOURCE=200809L";
# Return a list of functions exported by a header, empty if an include
# of the header does not compile.
sub list_exported_functions {
my ($cc, $standard, $header, $tmpdir) = @_;
my ($cc, $standard, $header, $tmpdir, $withclang) = @_;
my ($cc_all) = "$cc -D_ISOMAC $CFLAGS{$standard}";
my ($tmpfile) = "$tmpdir/list-$$.c";
my ($auxfile) = "$tmpdir/list-$$.c.aux";
my ($astfile) = "$tmpdir/list-$$.c.ast";
my ($ret);
my (%res) = ();
open (TMPFILE, ">$tmpfile") || die ("open $tmpfile: $!\n");
print TMPFILE "#include <$header>\n";
close (TMPFILE) || die ("close $tmpfile: $!\n");
if ($withclang ne "yes") {
$ret = system "$cc_all -c $tmpfile -o /dev/null -aux-info $auxfile > /dev/null";
} else {
$ret = system "$cc_all -c $tmpfile -o /dev/null -Xclang -ast-dump |grep FunctionDecl > $astfile";
}
unlink ($tmpfile) || die ("unlink $tmpfile: $!\n");
if ($ret != 0) {
return;
}
if ($withclang ne "yes") {
open (AUXFILE, "<$auxfile") || die ("open $auxfile: $!\n");
while (<AUXFILE>) {
s|/\*.*?\*/||g;
@@ -70,5 +76,20 @@ sub list_exported_functions {
}
close (AUXFILE) || die ("close $auxfile: $!\n");
unlink ($auxfile) || die ("unlink $auxfile: $!\n");
} else {
open (ASTFILE, "<$astfile") || die ("open $astfile: $!\n");
while (<ASTFILE>) {
s/^.*:[0-9][0-9]*:[0-9][0-9]* //g;
s/^.*:[0-9][0-9]* implicit //g;
s/^.*:[0-9][0-9]* //g;
if (/(\w+)\s* /) {
$res{$1} = 1;
} else {
die ("couldn't parse -ast-dump output: $_\n");
}
}
close (ASTFILE) || die ("close $astfile: $!\n");
unlink ($astfile) || die ("unlink $astfile: $!\n");
}
return sort keys %res;
}
+3
View File
@@ -178,6 +178,7 @@ $(conformtest-header-tests): $(objpfx)%/conform.out: \
$(PERL) -I. conformtest.pl --tmpdir=$(@D)/scratch --cc='$(CC)' \
--flags='$(conformtest-cc-flags)' --standard=$$std \
--headers=$$hdr $(conformtest-xfail) $(conformtest-cross) \
--withclang='$(with-clang)' \
> $@); \
$(evaluate-test)
@@ -185,6 +186,7 @@ $(linknamespace-symlists-tests): $(objpfx)symlist-%: list-header-symbols.pl
$(PERL) -I. -w $< --tmpdir=$(objpfx) --cc='$(CC)' \
--flags='$(conformtest-cc-flags)' --standard=$* \
--headers="$(strip $(conformtest-headers-$*))" \
--withclang='$(with-clang)' \
> $@ 2> $@.err; \
$(evaluate-test)
@@ -225,6 +227,7 @@ $(linknamespace-header-tests): $(objpfx)%/linknamespace.out: \
--stdsyms=$(objpfx)symlist-$$std --header=$$hdr \
--libsyms=$(objpfx)symlist-stdlibs-$$std \
--readelf='$(READELF)' \
--withclang='$(with-clang)' \
> $@ 2>&1); \
$(evaluate-test)
+9 -1
View File
@@ -11,7 +11,7 @@ $cross = "";
$xfail_str = "";
GetOptions ('headers=s' => \@headers, 'standard=s' => \$standard,
'flags=s' => \$flags, 'cc=s' => \$CC, 'tmpdir=s' => \$tmpdir,
'cross' => \$cross, 'xfail=s' => \$xfail_str);
'cross' => \$cross, 'xfail=s' => \$xfail_str, 'withclang=s' => \$withclang);
@headers = split(/,/,join(',',@headers));
# List of the headers we are testing.
@@ -270,9 +270,17 @@ sub checknamespace {
close (TESTFILE);
undef %errors;
if ($withclang eq "yes") {
open (CONTENT, "$CC $CFLAGS_namespace -E $fnamebase.c -P -Wp,-dM | sed -e '/^# [1-9]/d' -e '/^[[:space:]]*\$/d' |");
} else {
open (CONTENT, "$CC $CFLAGS_namespace -E $fnamebase.c -P -Wp,-dN | sed -e '/^# [1-9]/d' -e '/^[[:space:]]*\$/d' |");
}
loop: while (<CONTENT>) {
chop;
if ($withclang eq "yes") {
# Filter extra output coming from -dM
s/^(#[^ ]+ [^ (]+).*$/$1/g;
}
if (/^#define (.*)/) {
newtoken ($1, @allow);
} elsif (/^#undef (.*)/) {
+46 -5
View File
@@ -27,7 +27,9 @@ use Getopt::Long;
GetOptions ('header=s' => \$header, 'standard=s' => \$standard,
'flags=s' => \$flags, 'cc=s' => \$CC, 'tmpdir=s' => \$tmpdir,
'stdsyms=s' => \$stdsyms_file, 'libsyms=s' => \$libsyms_file,
'readelf=s' => \$READELF);
'readelf=s' => \$READELF, 'withclang=s' => \$withclang);
$debug = 1;
# Load the list of symbols that are OK.
%stdsyms = ();
@@ -162,7 +164,7 @@ foreach my $sym (@sym_data) {
# detected by this script if the same namespace issue applies for
# static linking.
@c_syms = list_exported_functions ("$CC $flags", $standard, $header, $tmpdir);
@c_syms = list_exported_functions ("$CC $flags", $standard, $header, $tmpdir, $withclang);
$cincfile = "$tmpdir/undef-$$.c";
$cincfile_o = "$tmpdir/undef-$$.o";
$cincfile_sym = "$tmpdir/undef-$$.sym";
@@ -177,9 +179,11 @@ system ("$CC $flags -D_ISOMAC $CFLAGS{$standard} -c $cincfile -o $cincfile_o")
system ("LC_ALL=C $READELF -W -s $cincfile_o > $cincfile_sym")
&& die ("readelf failed\n");
@elf_syms = list_syms ($cincfile_sym);
unlink ($cincfile) || die ("unlink $cincfile: $!\n");
unlink ($cincfile_o) || die ("unlink $cincfile_o: $!\n");
unlink ($cincfile_sym) || die ("unlink $cincfile_sym: $!\n");
if (!$debug) {
unlink ($cincfile) || die ("unlink $cincfile: $!\n");
unlink ($cincfile_o) || die ("unlink $cincfile_o: $!\n");
unlink ($cincfile_sym) || die ("unlink $cincfile_sym: $!\n");
}
%seen_where = ();
%files_seen = ();
@@ -207,7 +211,31 @@ while (%current_undef) {
$seen_where{$ssym} = "$current_undef{$sym} -> [$file] $ssym";
}
}
# A clang build can leave strong undefined symbols in the file,
# instead of GC'ing them; filter them out.
foreach my $usym (@{$strong_undef_syms{$file}}) {
$alsoseen = 0;
foreach my $ssym (@{$seen_syms{$file}}) {
if ($ssym eq $usym) {
if ($debug) {
print "$usym is strong undef also seen in $file, skipping\n";
}
$alsoseen = 1;
last;
}
}
if ($alsoseen) {
next;
}
if ($debug) {
foreach my $file2 (@{$sym_objs{$sym}}) {
foreach my $ssym (@{$seen_syms{$file2}}) {
if ($ssym eq $usym) {
print " seen in $file2";
}
}
}
}
if (!defined ($all_undef{$usym})) {
$all_undef{$usym} = "$current_undef{$sym} -> [$file] $usym";
$new_undef{$usym} = "$current_undef{$sym} -> [$file] $usym";
@@ -220,14 +248,27 @@ while (%current_undef) {
$ret = 0;
foreach my $sym (sort keys %seen_where) {
if ($debug) {
print "RAW $seen_where{$sym}\n";
}
if ($sym =~ /^_/) {
next;
}
if (defined ($stdsyms{$sym})) {
if ($debug) {
print "$sym IS IN stdsyms\n";
}
next;
}
if ($debug) {
print "FINAL ";
}
print "$seen_where{$sym}\n";
$ret = 1;
}
if ($debug) {
print "Return result is $ret\n";
}
exit $ret;
+2 -2
View File
@@ -24,7 +24,7 @@ use GlibcConform;
use Getopt::Long;
GetOptions ('headers=s' => \$headers, 'standard=s' => \$standard,
'flags=s' => \$flags, 'cc=s' => \$CC, 'tmpdir=s' => \$tmpdir);
'flags=s' => \$flags, 'cc=s' => \$CC, 'tmpdir=s' => \$tmpdir, 'withclang=s' => \$withclang);
@headers = split (/\s+/, $headers);
# Extra symbols possibly not found through -aux-info but still
@@ -67,7 +67,7 @@ $extra_syms{"POSIX2008"} = ["errno", "setjmp", "va_end", "environ",
%user_syms = ();
foreach my $header (@headers) {
@syms = list_exported_functions ("$CC $flags", $standard, $header, $tmpdir);
@syms = list_exported_functions ("$CC $flags", $standard, $header, $tmpdir, $withclang);
foreach my $sym (@syms) {
if ($sym !~ /^_/) {
$user_syms{$sym} = 1;
+13 -1
View File
@@ -105,8 +105,20 @@ include ../Rules
# Make these in the lib pass so they're available in time to link things with.
subdir_lib: $(extra-objs:%=$(objpfx)%)
ifeq ($(LLVM_OBJCOPY),)
OBJCOPY_FOR_ADDRSIG = ${OBJCOPY}
else
OBJCOPY_FOR_ADDRSIG = ${LLVM_OBJCOPY}
endif
define link-relocatable
$(CC) -nostdlib -nostartfiles -r -o $@ $^
$(CC) -nostdlib -nostartfiles -r -o $@.precopy $^
# Remove a section generated by clang for safe ICF; when lld links and
# retains relocs, the section is garbled and causes errors in later
# links done with --icf=safe. The removal can be unconditional as it
# is a no-op for non-clang/lld.
$(OBJCOPY_FOR_ADDRSIG) --remove-section=.llvm_addrsig $@.precopy $@
rm $@.precopy
endef
ifndef start-installed-name-rule
+3 -4
View File
@@ -39,8 +39,7 @@
static void
check_one_fd (int fd, int mode)
{
/* Note that fcntl() with this parameter is not a cancellation point. */
if (__builtin_expect (__libc_fcntl (fd, F_GETFD), 0) == -1
if (__builtin_expect (__fcntl_nocancel (fd, F_GETFD), 0) == -1
&& errno == EBADF)
{
const char *name;
@@ -50,12 +49,12 @@ check_one_fd (int fd, int mode)
if ((mode & O_ACCMODE) == O_WRONLY)
{
name = _PATH_DEV "full";
dev = makedev (DEV_FULL_MAJOR, DEV_FULL_MINOR);
dev = __gnu_dev_makedev (DEV_FULL_MAJOR, DEV_FULL_MINOR);
}
else
{
name = _PATH_DEVNULL;
dev = makedev (DEV_NULL_MAJOR, DEV_NULL_MINOR);
dev = __gnu_dev_makedev (DEV_NULL_MAJOR, DEV_NULL_MINOR);
}
/* Something is wrong with this descriptor, it's probably not
+2
View File
@@ -45,9 +45,11 @@ tolower (int c)
{
return c >= -128 && c < 256 ? __ctype_tolower[c] : c;
}
libc_hidden_def (tolower)
int
toupper (int c)
{
return c >= -128 && c < 256 ? __ctype_toupper[c] : c;
}
libc_hidden_def (toupper)
+3
View File
@@ -11,6 +11,9 @@ libdl {
GLIBC_2.3.4 {
dlmopen;
}
GLIBC_2.15 {
__google_dlopen_with_offset; __google_dlmopen_with_offset;
}
GLIBC_PRIVATE {
_dlfcn_hook;
}
+12
View File
@@ -22,6 +22,7 @@
#include <features.h>
#define __need_size_t
#include <stddef.h>
#include <sys/types.h>
/* Collect various system dependent definitions and declarations. */
#include <bits/dlfcn.h>
@@ -55,6 +56,11 @@ __BEGIN_DECLS
passed to `dlsym' to get symbol values from it. */
extern void *dlopen (const char *__file, int __mode) __THROWNL;
/* Same as above, but ELF header is at OFF from the start of file. */
extern void *__google_dlopen_with_offset (__const char *__file,
off_t offset,
int __mode) __THROW;
/* Unmap and close a shared object opened by `dlopen'.
The handle cannot be used again after calling `dlclose'. */
extern int dlclose (void *__handle) __THROWNL __nonnull ((1));
@@ -68,6 +74,12 @@ extern void *dlsym (void *__restrict __handle,
/* Like `dlopen', but request object to be allocated in a new namespace. */
extern void *dlmopen (Lmid_t __nsid, const char *__file, int __mode) __THROWNL;
/* Same as above, but ELF header is at OFF from the start of file. */
extern void *__google_dlmopen_with_offset (Lmid_t __nsid,
__const char *__file,
off_t offset,
int __mode) __THROW;
/* Find the run-time address in the shared object HANDLE refers to
of the symbol called NAME with VERSION. */
extern void *dlvsym (void *__restrict __handle,
+46 -12
View File
@@ -30,7 +30,9 @@ dlmopen (Lmid_t nsid, const char *file, int mode)
{
return __dlmopen (nsid, file, mode, RETURN_ADDRESS (0));
}
#if 0 // Google-local
static_link_warning (dlmopen)
#endif
#else
@@ -38,6 +40,8 @@ struct dlmopen_args
{
/* Namespace ID. */
Lmid_t nsid;
/* ELF header at offset in file. */
off_t offset;
/* The arguments for dlopen_doit. */
const char *file;
int mode;
@@ -68,13 +72,52 @@ dlmopen_doit (void *a)
_dl_signal_error (EINVAL, NULL, NULL, N_("invalid mode"));
}
args->new = GLRO(dl_open) (args->file ?: "", args->mode | __RTLD_DLOPEN,
args->new = GLRO(dl_open) (args->file ?: "", args->offset, args->mode | __RTLD_DLOPEN,
args->caller,
args->nsid, __dlfcn_argc, __dlfcn_argv,
__environ);
}
static void *
__dlmopen_common (struct dlmopen_args *args)
{
# ifdef SHARED
return _dlerror_run (dlmopen_doit, args) ? NULL : args->new;
# else
if (_dlerror_run (dlmopen_doit, args))
return NULL;
__libc_register_dl_open_hook ((struct link_map *) args->new);
__libc_register_dlfcn_hook ((struct link_map *) args->new);
return args->new;
# endif
}
void *
__dlmopen_with_offset (Lmid_t nsid, const char *file, off_t offset,
int mode DL_CALLER_DECL)
{
# ifdef SHARED
if (!rtld_active ())
return _dlfcn_hook->dlmopen_with_offset (nsid, file, offset, mode, RETURN_ADDRESS (0));
# endif
struct dlmopen_args oargs;
oargs.nsid = nsid;
oargs.file = file;
oargs.offset = offset;
oargs.mode = mode;
oargs.caller = DL_CALLER;
return __dlmopen_common (&oargs);
}
# ifdef SHARED
strong_alias (__dlmopen_with_offset, __google_dlmopen_with_offset)
# endif
void *
__dlmopen (Lmid_t nsid, const char *file, int mode DL_CALLER_DECL)
{
@@ -86,20 +129,11 @@ __dlmopen (Lmid_t nsid, const char *file, int mode DL_CALLER_DECL)
struct dlmopen_args args;
args.nsid = nsid;
args.file = file;
args.offset = 0;
args.mode = mode;
args.caller = DL_CALLER;
# ifdef SHARED
return _dlerror_run (dlmopen_doit, &args) ? NULL : args.new;
# else
if (_dlerror_run (dlmopen_doit, &args))
return NULL;
__libc_register_dl_open_hook ((struct link_map *) args.new);
__libc_register_dlfcn_hook ((struct link_map *) args.new);
return args.new;
# endif
return __dlmopen_common (&args);
}
# ifdef SHARED
strong_alias (__dlmopen, dlmopen)
+41 -12
View File
@@ -29,7 +29,9 @@ dlopen (const char *file, int mode)
{
return __dlopen (file, mode, RETURN_ADDRESS (0));
}
#if 0 // Google-local
static_link_warning (dlopen)
#endif
#else
@@ -37,6 +39,8 @@ struct dlopen_args
{
/* The arguments for dlopen_doit. */
const char *file;
/* ELF header at offset in file. */
off_t offset;
int mode;
/* The return value of dlopen_doit. */
void *new;
@@ -63,13 +67,47 @@ dlopen_doit (void *a)
| __RTLD_SPROF))
_dl_signal_error (0, NULL, NULL, _("invalid mode parameter"));
args->new = GLRO(dl_open) (args->file ?: "", args->mode | __RTLD_DLOPEN,
args->new = GLRO(dl_open) (args->file ?: "", args->offset, args->mode | __RTLD_DLOPEN,
args->caller,
args->file == NULL ? LM_ID_BASE : NS,
__dlfcn_argc, __dlfcn_argv, __environ);
}
static void *
__dlopen_common (struct dlopen_args *args)
{
# ifdef SHARED
return _dlerror_run (dlopen_doit, args) ? NULL : args->new;
# else
if (_dlerror_run (dlopen_doit, args))
return NULL;
__libc_register_dl_open_hook ((struct link_map *) args->new);
__libc_register_dlfcn_hook ((struct link_map *) args->new);
return args->new;
# endif
}
# ifdef SHARED
void *
__dlopen_with_offset (const char *file, off_t offset, int mode DL_CALLER_DECL)
{
if (!rtld_active ())
return _dlfcn_hook->dlopen_with_offset (file, offset, mode, DL_CALLER);
struct dlopen_args oargs;
oargs.file = file;
oargs.offset = offset;
oargs.mode = mode;
oargs.caller = DL_CALLER;
return __dlopen_common (&oargs);
}
strong_alias (__dlopen_with_offset, __google_dlopen_with_offset)
# endif
void *
__dlopen (const char *file, int mode DL_CALLER_DECL)
{
@@ -80,20 +118,11 @@ __dlopen (const char *file, int mode DL_CALLER_DECL)
struct dlopen_args args;
args.file = file;
args.offset = 0;
args.mode = mode;
args.caller = DL_CALLER;
# ifdef SHARED
return _dlerror_run (dlopen_doit, &args) ? NULL : args.new;
# else
if (_dlerror_run (dlopen_doit, &args))
return NULL;
__libc_register_dl_open_hook ((struct link_map *) args.new);
__libc_register_dlfcn_hook ((struct link_map *) args.new);
return args.new;
# endif
return __dlopen_common (&args);
}
# ifdef SHARED
# include <shlib-compat.h>
+1 -1
View File
@@ -51,7 +51,7 @@ dlopen_doit (void *a)
{
struct dlopen_args *args = (struct dlopen_args *) a;
args->new = GLRO(dl_open) (args->file ?: "", args->mode | __RTLD_DLOPEN,
args->new = GLRO(dl_open) (args->file ?: "", 0, args->mode | __RTLD_DLOPEN,
args->caller,
args->file == NULL ? LM_ID_BASE : NS,
__dlfcn_argc, __dlfcn_argv, __environ);
+136 -9
View File
@@ -62,6 +62,9 @@ rtld-routines = rtld $(all-dl-routines) dl-sysdep dl-environ dl-minimal \
dl-error-minimal dl-conflict
all-rtld-routines = $(rtld-routines) $(sysdep-rtld-routines)
# Hack around a clang alias+optimization problem.
CFLAGS-rtld.c += -O0
CFLAGS-dl-runtime.c += -fexceptions -fasynchronous-unwind-tables
CFLAGS-dl-lookup.c += -fexceptions -fasynchronous-unwind-tables
CFLAGS-dl-iterate-phdr.c += $(uses-callbacks)
@@ -149,7 +152,7 @@ tests-static-normal := tst-leaks1-static tst-array1-static tst-array5-static \
tst-dl-iter-static \
tst-tlsalign-static tst-tlsalign-extern-static \
tst-linkall-static tst-env-setuid tst-env-setuid-tunables
tests-static-internal := tst-tls1-static tst-tls2-static \
tests-static-internal := tst-tls1-static \
tst-ptrguard1-static tst-stackguard1-static \
tst-tls1-static-non-pie tst-libc_dlvsym-static
@@ -159,7 +162,7 @@ tst-tls1-static-non-pie-no-pie = yes
tests := tst-tls9 tst-leaks1 \
tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 \
tst-auxv
tests-internal := tst-tls1 tst-tls2 $(tests-static-internal)
tests-internal := tst-tls1 $(tests-static-internal)
tests-static := $(tests-static-normal) $(tests-static-internal)
ifeq (yes,$(build-shared))
@@ -177,6 +180,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
tst-tls16 tst-tls17 tst-tls18 tst-tls19 tst-tls-dlinfo \
tst-align tst-align2 $(tests-execstack-$(have-z-execstack)) \
tst-dlmodcount tst-dlopenrpath tst-deep1 \
tst-dlopen-offset \
tst-dlmopen1 tst-dlmopen3 \
unload3 unload4 unload5 unload6 unload7 unload8 tst-global1 order2 \
tst-audit1 tst-audit2 tst-audit8 tst-audit9 \
@@ -187,7 +191,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \
tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload \
tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose \
tst-debug1 tst-main1
tst-debug1 tst-main1 tst-big-note
# reldep9
tests-internal += loadtest unload unload2 circleload1 \
neededtest neededtest2 neededtest3 neededtest4 \
@@ -200,9 +204,49 @@ endif
test-srcs = tst-pathopt
selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null)
ifneq ($(selinux-enabled),1)
ifneq ($(with-clang),yes)
tests-execstack-yes = tst-execstack tst-execstack-needed tst-execstack-prog
endif
endif
endif
ifeq ($(have-dt-relr),yes)
tests += \
tst-relr \
tst-relr2 \
tst-relr3 \
tst-relr4 \
# tests
modules-names-dt-relr = \
tst-relr-mod2 \
tst-relr-mod3a \
tst-relr-mod3b \
tst-relr-mod4a \
tst-relr-mod4b \
# modules-names-dt-relr
modules-names += $(modules-names-dt-relr)
# These shared libraries have special build rules.
modules-names-nobuild += $(modules-names-dt-relr)
ifeq ($(have-fpie),yes)
tests += \
tst-relr-pie \
# tests
tests-pie += \
tst-relr-pie \
# tests-pie
tests-special += \
$(objpfx)check-tst-relr-pie.out \
# tests-special
endif
CFLAGS-tst-relr-pie.c += $(pie-ccflag)
LDFLAGS-tst-relr += -Wl,-z,pack-relative-relocs
LDFLAGS-tst-relr-pie += -Wl,-z,pack-relative-relocs
LDFLAGS-tst-relr2 += -Wl,--allow-shlib-undefined
CFLAGS-tst-relr-mod2.c += $(no-stack-protector)
CFLAGS-tst-relr-mod3a.c += $(no-stack-protector)
CFLAGS-tst-relr-mod3b.c += $(no-stack-protector)
CFLAGS-tst-relr-mod4a.c += $(no-stack-protector)
CFLAGS-tst-relr-mod4b.c += $(no-stack-protector)
endif
ifeq ($(run-built-tests),yes)
tests-special += $(objpfx)tst-leaks1-mem.out \
$(objpfx)tst-leaks1-static-mem.out $(objpfx)noload-mem.out \
@@ -272,7 +316,10 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 \
tst-latepthreadmod $(tst-tls-many-dynamic-modules) \
tst-nodelete-dlclose-dso tst-nodelete-dlclose-plugin \
tst-main1mod tst-libc_dlvsym-dso
tst-dlopen-offset-mod1 tst-dlopen-offset-mod2 tst-dlopen-offset-mod3 \
tst-main1mod tst-libc_dlvsym-dso \
tst-big-note-lib
ifeq (yes,$(have-mtls-dialect-gnu2))
tests += tst-gnu2-tls1
modules-names += tst-gnu2-tls1mod
@@ -280,6 +327,8 @@ $(objpfx)tst-gnu2-tls1: $(objpfx)tst-gnu2-tls1mod.so
tst-gnu2-tls1mod.so-no-z-defs = yes
CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2
endif
# Somehow configure is failing to notice that lld can't do protected data.
ifeq ($(with-lld),no)
ifeq (yes,$(have-protected-data))
modules-names += tst-protected1moda tst-protected1modb
tests += tst-protected1a tst-protected1b
@@ -294,6 +343,7 @@ tst-protected1modb.so-no-z-defs = yes
test-xfail-tst-protected1a = yes
test-xfail-tst-protected1b = yes
endif
endif # lld
ifeq (yesyes,$(have-fpie)$(build-shared))
modules-names += tst-piemod1
tests += tst-pie1 tst-pie2
@@ -304,7 +354,9 @@ tests-pie += vismain
CFLAGS-vismain.c += $(PIE-ccflag)
endif
endif
ifneq ($(with-clang),yes)
modules-execstack-yes = tst-execstack-mod
endif
extra-test-objs += $(addsuffix .os,$(strip $(modules-names)))
# filtmod1.so has a special rule
@@ -322,11 +374,15 @@ tests-static += $(tests-ifuncstatic)
tests-internal += $(tests-ifuncstatic)
ifeq (yes,$(build-shared))
tests-internal += \
ifuncmain1 ifuncmain1pic ifuncmain1vis ifuncmain1vispic \
ifuncmain1pic ifuncmain1vis ifuncmain1vispic \
ifuncmain1staticpic \
ifuncmain2 ifuncmain2pic ifuncmain3 ifuncmain4 \
ifuncmain5 ifuncmain5pic ifuncmain5staticpic \
ifuncmain5pic ifuncmain5staticpic \
ifuncmain7 ifuncmain7pic
ifneq ($(with-clang),yes)
# Skip over tests where lld errors with "cannot preempt symbol"
tests-internal += ifuncmain1 ifuncmain5
endif
ifunc-test-modules = ifuncdep1 ifuncdep1pic ifuncdep2 ifuncdep2pic \
ifuncdep5 ifuncdep5pic
extra-test-objs += $(ifunc-test-modules:=.o)
@@ -440,10 +496,13 @@ $(objpfx)librtld.map: $(objpfx)dl-allobjs.os $(common-objpfx)libc_pic.a
rm -f $@.o
mv -f $@T $@
# For lld, add to regexp below for optional address and size to be at front of line.
# Also, Google b/79865038 reports that make 3.81 can segfault while iterating over
# the repeated lib+file entries in the map; work around with sort -u .
$(objpfx)librtld.mk: $(objpfx)librtld.map Makefile
LC_ALL=C \
sed -n 's@^$(common-objpfx)\([^(]*\)(\([^)]*\.os\)) *.*$$@\1 \2@p' \
$< | \
sed -n 's@^[0-9a-f ]*$(common-objpfx)\([^(]*\)(\([^)]*\.os\)) *.*$$@\1 \2@p' \
$< | LC_ALL=C sort -u | \
while read lib file; do \
case $$lib in \
libc_pic.a) \
@@ -631,7 +690,7 @@ $(objpfx)unload6mod2.so: $(libdl)
$(objpfx)unload6mod3.so: $(libdl)
$(objpfx)unload7mod1.so: $(libdl)
$(objpfx)unload7mod2.so: $(objpfx)unload7mod1.so
$(objpfx)unload8mod1.so: $(objpfx)unload8mod2.so
$(objpfx)unload8mod1.so: $(objpfx)unload8mod2.so $(libdl)
$(objpfx)unload8mod2.so: $(objpfx)unload8mod3.so
$(objpfx)unload8mod3.so: $(libdl)
$(objpfx)tst-initordera2.so: $(objpfx)tst-initordera1.so
@@ -1277,6 +1336,11 @@ $(objpfx)tst-unique2.out: $(objpfx)tst-unique2mod2.so
$(objpfx)tst-unique3: $(libdl) $(objpfx)tst-unique3lib.so
$(objpfx)tst-unique3.out: $(objpfx)tst-unique3lib2.so
# clang optimization drops seemingly-unused instantiations
ifeq ($(with-clang),yes)
CFLAGS-tst-unique4lib.cc += -O0
endif
$(objpfx)tst-unique4: $(objpfx)tst-unique4lib.so
$(objpfx)tst-nodelete: $(libdl)
@@ -1446,3 +1510,66 @@ $(objpfx)tst-libc_dlvsym-static: $(common-objpfx)dlfcn/libdl.a
tst-libc_dlvsym-static-ENV = \
LD_LIBRARY_PATH=$(objpfx):$(common-objpfx):$(common-objpfx)dlfcn
$(objpfx)tst-libc_dlvsym-static.out: $(objpfx)tst-libc_dlvsym-dso.so
$(objpfx)tst-dlopen-offset: $(libdl)
$(objpfx)tst-dlopen-offset.out: $(objpfx)tst-dlopen-offset-comb.so
$(objpfx)tst-dlopen-offset-comb.so: $(objpfx)tst-dlopen-offset-mod1.so $(objpfx)tst-dlopen-offset-mod2.so $(objpfx)tst-dlopen-offset-mod3.so
dd if=$(objpfx)tst-dlopen-offset-mod1.so of=$(objpfx)tst-dlopen-offset-comb.so bs=1024 seek=64
dd if=$(objpfx)tst-dlopen-offset-mod2.so of=$(objpfx)tst-dlopen-offset-comb.so bs=1024 seek=128
dd if=$(objpfx)tst-dlopen-offset-mod3.so of=$(objpfx)tst-dlopen-offset-comb.so bs=1024 seek=192
$(objpfx)tst-big-note: $(objpfx)tst-big-note-lib.so
$(objpfx)check-tst-relr-pie.out: $(objpfx)tst-relr-pie
LC_ALL=C $(OBJDUMP) -p $< \
| sed -ne '/required from libc.so/,$$ p' \
| grep GLIBC_ABI_DT_RELR > $@; \
$(evaluate-test)
# The test checks if a DT_RELR shared library without DT_NEEDED works as
# intended, so it uses an explicit link rule.
$(objpfx)tst-relr2: $(objpfx)tst-relr-mod2.so
$(objpfx)tst-relr-mod2.so: $(objpfx)tst-relr-mod2.os
$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
$(LDFLAGS-soname-fname) \
-shared -o $@.new $(filter-out $(map-file),$^)
$(call after-link,$@.new)
mv -f $@.new $@
# The test checks if a DT_RELR shared library without DT_VERNEED works as
# intended, so it uses an explicit link rule.
$(objpfx)tst-relr3: $(objpfx)tst-relr-mod3a.so
$(objpfx)tst-relr-mod3b.so: $(objpfx)tst-relr-mod3b.os
$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
$(LDFLAGS-soname-fname) \
-shared -o $@.new $(filter-out $(map-file),$^)
$(call after-link,$@.new)
mv -f $@.new $@
$(objpfx)tst-relr-mod3a.so: $(objpfx)tst-relr-mod3a.os \
$(objpfx)tst-relr-mod3b.so
$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
$(LDFLAGS-soname-fname) \
-shared -o $@.new $(filter-out $(map-file),$^)
$(call after-link,$@.new)
mv -f $@.new $@
# The test checks if a DT_RELR shared library without libc.so on DT_NEEDED
# works as intended, so it uses an explicit link rule.
$(objpfx)tst-relr4: $(objpfx)tst-relr-mod4a.so
$(objpfx)tst-relr-mod4b.so: $(objpfx)tst-relr-mod4b.os
$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
$(LDFLAGS-soname-fname) \
-Wl,--version-script=tst-relr-mod4b.map \
-shared -o $@.new $(filter-out $(map-file),$^)
$(call after-link,$@.new)
mv -f $@.new $@
$(objpfx)tst-relr-mod4a.so: $(objpfx)tst-relr-mod4a.os \
$(objpfx)tst-relr-mod4b.so
$(LINK.o) -nostdlib -nostartfiles -Wl,-z,pack-relative-relocs \
$(LDFLAGS-soname-fname) \
-shared -o $@.new $(filter-out $(map-file),$^)
$(call after-link,$@.new)
mv -f $@.new $@
+8
View File
@@ -20,6 +20,11 @@ libc {
__register_frame_info_table_bases; _Unwind_Find_FDE;
}
%endif
GLIBC_ABI_DT_RELR {
# This symbol is used only for empty version map and will be removed
# by scripts/versions.awk.
__placeholder_only_for_empty_version_map;
}
GLIBC_PRIVATE {
# functions used in other libraries
_dl_addr;
@@ -61,6 +66,7 @@ ld {
_dl_argv; _dl_find_dso_for_object; _dl_get_tls_static_info;
_dl_deallocate_tls; _dl_make_stack_executable;
_dl_rtld_di_serinfo; _dl_starting_up;
_dl_clear_dtv;
_rtld_global; _rtld_global_ro;
# Only here for gdb while a better method is developed.
@@ -78,5 +84,7 @@ ld {
# Set value of a tunable.
__tunable_get_val;
_google_dl_debug_state_hook;
}
}
+9
View File
@@ -135,6 +135,12 @@ _dl_close_worker (struct link_map *map, bool force)
Lmid_t nsid = map->l_ns;
struct link_namespaces *ns = &GL(dl_ns)[nsid];
/* Recompute _ns_last next time we need it.
It is tempting to set _ns_last to map->l_prev, but map->l_prev might also
be going away as part of current dlclose, and using it may cause _ns_last
to become dangling. */
ns->_ns_last = NULL;
retry:
dl_close_state = pending;
@@ -717,6 +723,9 @@ _dl_close_worker (struct link_map *map, bool force)
_dl_debug_printf ("\nfile=%s [%lu]; destroying link map\n",
imap->l_name, imap->l_ns);
/* Remove from hashtables. */
_dl_hash_del_object (imap);
/* This name always is allocated. */
free (imap->l_name);
/* Remove the list with all the names of the shared object. */
+42 -11
View File
@@ -27,17 +27,8 @@
#include <sys/types.h>
#include "dynamic-link.h"
void
_dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
ElfW(Rela) *conflictend)
{
#if ! ELF_MACHINE_NO_RELA
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC))
_dl_debug_printf ("\nconflict processing: %s\n", DSO_FILENAME (l->l_name));
#ifndef NESTING
{
/* Do the conflict relocation of the object and library GOT and other
data. */
/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */
#define RESOLVE_MAP(ref, version, flags) (*ref = NULL, NULL)
@@ -51,13 +42,49 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
(map) = resolve_conflict_map; \
} while (0)
#include "dynamic-link.h"
#endif /* n NESTING */
void
_dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
ElfW(Rela) *conflictend)
{
#if ! ELF_MACHINE_NO_RELA
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC))
_dl_debug_printf ("\nconflict processing: %s\n", DSO_FILENAME (l->l_name));
{
/* Do the conflict relocation of the object and library GOT and other
data. */
#ifdef NESTING
/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */
#define RESOLVE_MAP(ref, version, flags) (*ref = NULL, NULL)
#define RESOLVE(ref, version, flags) (*ref = NULL, 0)
#define RESOLVE_CONFLICT_FIND_MAP(map, r_offset) \
do { \
while ((resolve_conflict_map->l_map_end < (ElfW(Addr)) (r_offset)) \
|| (resolve_conflict_map->l_map_start > (ElfW(Addr)) (r_offset))) \
resolve_conflict_map = resolve_conflict_map->l_next; \
\
(map) = resolve_conflict_map; \
} while (0)
#endif /* NESTING */
/* Prelinking makes no sense for anything but the main namespace. */
assert (l->l_ns == LM_ID_BASE);
struct link_map *resolve_conflict_map __attribute__ ((__unused__))
= GL(dl_ns)[LM_ID_BASE]._ns_loaded;
#ifdef NESTING
#include "dynamic-link.h"
#endif /* NESTING */
/* Override these, defined in dynamic-link.h. */
#undef CHECK_STATIC_TLS
#define CHECK_STATIC_TLS(ref_map, sym_map) ((void) 0)
@@ -68,7 +95,11 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
for (; conflict < conflictend; ++conflict)
elf_machine_rela (l, conflict, NULL, NULL, (void *) conflict->r_offset,
0);
0
#ifndef NESTING
, NULL
#endif
);
}
#endif
}
+4
View File
@@ -64,6 +64,8 @@ _dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns)
}
void (*_google_dl_debug_state_hook)(const struct r_debug *);
/* This function exists solely to have a breakpoint set on it by the
debugger. The debugger is supposed to find this function's address by
examining the r_brk member of struct r_debug, but GDB 4.15 in fact looks
@@ -71,5 +73,7 @@ _dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns)
void
_dl_debug_state (void)
{
if (_google_dl_debug_state_hook)
_google_dl_debug_state_hook(&_r_debug);
}
rtld_hidden_def (_dl_debug_state)
+1 -1
View File
@@ -60,7 +60,7 @@ openaux (void *a)
{
struct openaux_args *args = (struct openaux_args *) a;
args->aux = _dl_map_object (args->map, args->name,
args->aux = _dl_map_object (args->map, args->name, 0,
(args->map->l_type == lt_executable
? lt_library : args->map->l_type),
args->trace_mode, args->open_mode,
+7 -2
View File
@@ -65,8 +65,13 @@
else \
dst_len = (l)->l_origin == (char *) -1 \
? 0 : strlen ((l)->l_origin); \
dst_len = MAX (MAX (dst_len, GLRO(dl_platformlen)), \
strlen (DL_DST_LIB)); \
\
const char *exec_origin = GLRO(google_exec_origin_dir); \
size_t exec_origin_len = \
(exec_origin == NULL) ? 0 : strlen (exec_origin); \
\
dst_len = MAX (MAX (MAX (dst_len, GLRO(dl_platformlen)), \
strlen (DL_DST_LIB)), exec_origin_len); \
if (dst_len > 4) \
__len += __cnt * (dst_len - 4); \
} \
+23
View File
@@ -85,6 +85,21 @@ fatal_error (int errcode, const char *objname, const char *occasion,
: ""));
}
/* Due to a complicated set of interactions with different symbol
versions, presumably including a VMX-specific __vmx__longjmp, PPC
clang ends calling __longjump with ld.so through the global entry
point (+0x0) instead of via the local entry point (+0x8) which
results in ld.so exceptions crashing because the TOC is not set up.
The hack here simply calls the function through a pointer, which
guarantees that the global entry point has the TOC set up. (This
may or may not be a clang bug, the symbol aliasing is tricky and
literally affects only __longjmp out of all the symbols in
libc.) */
#if defined __clang__ && defined __powerpc64__
volatile void (*longjmpptr) (struct __jmp_buf_tag __env[1], int __val)
__attribute__ ((__nothrow__)) __attribute__ ((__noreturn__)) = __longjmp;
#endif
void
_dl_signal_exception (int errcode, struct dl_exception *exception,
const char *occasion)
@@ -96,7 +111,11 @@ _dl_signal_exception (int errcode, struct dl_exception *exception,
*lcatch->errcode = errcode;
/* We do not restore the signal mask because none was saved. */
#if defined __clang__ && defined __powerpc64__
(*longjmpptr) (lcatch->env[0].__jmpbuf, 1);
#else
__longjmp (lcatch->env[0].__jmpbuf, 1);
#endif
}
else
fatal_error (errcode, exception->objname, occasion, exception->errstring);
@@ -118,7 +137,11 @@ _dl_signal_error (int errcode, const char *objname, const char *occation,
*lcatch->errcode = errcode;
/* We do not restore the signal mask because none was saved. */
#if defined __clang__ && defined __powerpc64__
(*longjmpptr) (lcatch->env[0].__jmpbuf, 1);
#else
__longjmp (lcatch->env[0].__jmpbuf, 1);
#endif
}
else
fatal_error (errcode, objname, occation, errstring);
+3 -1
View File
@@ -59,6 +59,7 @@ struct do_dlopen_args
{
/* Argument to do_dlopen. */
const char *name;
off_t offset;
/* Opening mode. */
int mode;
/* This is the caller of the dlopen() function. */
@@ -93,7 +94,7 @@ do_dlopen (void *ptr)
{
struct do_dlopen_args *args = (struct do_dlopen_args *) ptr;
/* Open and relocate the shared object. */
args->map = GLRO(dl_open) (args->name, args->mode, args->caller_dlopen,
args->map = GLRO(dl_open) (args->name, args->offset, args->mode, args->caller_dlopen,
__LM_ID_CALLER, __libc_argc, __libc_argv,
__environ);
}
@@ -186,6 +187,7 @@ __libc_dlopen_mode (const char *name, int mode)
{
struct do_dlopen_args args;
args.name = name;
args.offset = 0;
args.mode = mode;
args.caller_dlopen = RETURN_ADDRESS (0);
+305 -77
View File
@@ -46,6 +46,9 @@
#include <dl-machine-reject-phdr.h>
#include <dl-sysdep-open.h>
/* Code below to add offset to symbol names references itoa. */
#include <_itoa.h>
#include <not-cancel.h>
#include <endian.h>
#if BYTE_ORDER == BIG_ENDIAN
@@ -232,7 +235,8 @@ _dl_dst_count (const char *name)
++name;
if ((len = is_dst (start, name, "ORIGIN", __libc_enable_secure)) != 0
|| (len = is_dst (start, name, "PLATFORM", 0)) != 0
|| (len = is_dst (start, name, "LIB", 0)) != 0)
|| (len = is_dst (start, name, "LIB", 0)) != 0
|| (len = is_dst (start, name, "EXEC_ORIGIN", 0)) != 0)
++cnt;
name = strchr (name + len, '$');
@@ -274,6 +278,13 @@ _dl_dst_substitute (struct link_map *l, const char *name, char *result)
repl = GLRO(dl_platform);
else if ((len = is_dst (start, name, "LIB", 0)) != 0)
repl = DL_DST_LIB;
else if ((len = is_dst (start, name, "EXEC_ORIGIN", 0)) != 0)
{
if (__libc_enable_secure)
_dl_fatal_printf ("$EXEC_ORIGIN rpath entry not allowed in setuid/setgid executables.\n");
repl = GLRO(google_exec_origin_dir);
}
if (repl != NULL && repl != (const char *) -1)
{
@@ -347,8 +358,7 @@ expand_dynamic_string_token (struct link_map *l, const char *s)
/* Add `name' to the list of names for a particular shared object.
`name' is expected to have been allocated with malloc and will
be freed if the shared object already has this name.
Returns false if the object already had this name. */
be freed if the shared object already has this name. */
static void
add_name_to_object (struct link_map *l, const char *name)
{
@@ -777,7 +787,7 @@ lose (int code, int fd, const char *name, char *realname, struct link_map *l,
{
/* The file might already be closed. */
if (fd != -1)
(void) __close (fd);
(void) __close_nocancel (fd);
if (l != NULL && l->l_origin != (char *) -1l)
free ((char *) l->l_origin);
free (l);
@@ -794,6 +804,177 @@ lose (int code, int fd, const char *name, char *realname, struct link_map *l,
}
/* Hash tables of loaded objects; one keyed on name, one keyed on inode. */
struct lib_hash_namenode
{
const char *name;
struct link_map *lib;
struct lib_hash_namenode *next;
uint32_t hash;
};
struct lib_hash_filenode
{
struct link_map *lib;
struct lib_hash_filenode *next;
uint32_t hash;
};
/* Must be a power of 2. */
#define LIB_HASH_BUCKETS 256
static struct lib_hash_namenode *lib_hash_nametable[LIB_HASH_BUCKETS];
static struct lib_hash_filenode *lib_hash_filetable[LIB_HASH_BUCKETS];
static size_t
lib_hash_bucket (uint32_t hash)
{
return hash & (LIB_HASH_BUCKETS-1);
}
static uint32_t
hash_mix (uint32_t h, size_t val)
{
h ^= val;
h *= 0x5bd1e995;
h ^= h >> 15;
val >>= 4 * sizeof val;
h ^= val;
h *= 0x5bd1e995;
h ^= h >> 15;
return h;
}
static struct link_map *
lib_hash_getname (Lmid_t nsid, const char *name)
{
uint32_t hash = hash_mix (dl_new_hash (name), nsid);
struct lib_hash_namenode *n = lib_hash_nametable[lib_hash_bucket (hash)];
while (n)
{
struct link_map *l = n->lib;
if (n->hash == hash && !strcmp (n->name, name) && l->l_ns == nsid && !l->l_removed)
return l;
n = n->next;
}
return NULL;
}
static void
lib_hash_addname (const char *name, struct link_map *lib)
{
if (lib->l_faked)
return;
struct lib_hash_namenode *n = malloc (sizeof (struct lib_hash_namenode));
if (!n)
_dl_fatal_printf ("%s: out of memory\n", __func__);
uint32_t hash = hash_mix (dl_new_hash (name), lib->l_ns);
struct lib_hash_namenode **p = lib_hash_nametable + lib_hash_bucket (hash);
n->name = name;
n->lib = lib;
n->next = *p;
n->hash = hash;
*p = n;
}
/* 'name' must be the exact pointer originally passed to lib_hash_addname(). */
static void
lib_hash_delname (const char *name, struct link_map *lib)
{
uint32_t hash = hash_mix (dl_new_hash (name), lib->l_ns);
struct lib_hash_namenode **p = lib_hash_nametable + lib_hash_bucket (hash);
while (*p)
{
struct lib_hash_namenode *n = *p;
if (n->hash == hash && n->lib == lib && n->name == name) {
*p = n->next;
free (n);
return;
}
p = &n->next;
}
_dl_fatal_printf ("%s: can't unhash '%s'\n", __func__, name);
}
static uint32_t
hash_file (Lmid_t nsid, dev_t dev, ino64_t ino, off_t off)
{
return hash_mix (hash_mix (hash_mix (hash_mix (0, nsid), dev), ino), off);
}
static struct link_map *
lib_hash_getfile (Lmid_t nsid, dev_t dev, ino64_t ino, off_t off)
{
uint32_t hash = hash_file (nsid, dev, ino, off);
struct lib_hash_filenode *n = lib_hash_filetable[lib_hash_bucket (hash)];
while (n)
{
struct link_map *l = n->lib;
if (n->hash == hash && !l->l_removed && l->l_ns == nsid &&
l->l_file_id.dev == dev && l->l_file_id.ino == ino && l->l_off == off)
return l;
n = n->next;
}
return NULL;
}
static void
lib_hash_addfile (struct link_map *lib)
{
if (lib->l_faked)
return;
struct lib_hash_filenode *n = malloc (sizeof (struct lib_hash_filenode));
if (!n)
_dl_fatal_printf ("%s: out of memory\n", __func__);
uint32_t hash = hash_file (lib->l_ns, lib->l_file_id.dev, lib->l_file_id.ino, lib->l_off);
struct lib_hash_filenode **p = lib_hash_filetable + lib_hash_bucket (hash);
n->lib = lib;
n->next = *p;
n->hash = hash;
*p = n;
}
static void
lib_hash_delfile (struct link_map *lib)
{
uint32_t hash = hash_file (lib->l_ns, lib->l_file_id.dev, lib->l_file_id.ino, lib->l_off);
struct lib_hash_filenode **p = lib_hash_filetable + lib_hash_bucket (hash);
while (*p)
{
struct lib_hash_filenode *n = *p;
if (n->hash == hash && n->lib == lib)
{
*p = n->next;
free (n);
return;
}
p = &n->next;
}
_dl_fatal_printf ("%s: can't unhash '%s'\n", __func__, lib->l_name);
}
void
_dl_hash_add_object (struct link_map *lib)
{
lib_hash_addfile (lib);
lib_hash_addname (lib->l_name, lib);
for (struct libname_list *ln = lib->l_libname; ln; ln = ln->next)
{
lib_hash_addname (ln->name, lib);
}
}
void
_dl_hash_del_object (struct link_map *lib)
{
lib_hash_delfile (lib);
lib_hash_delname (lib->l_name, lib);
for (struct libname_list *ln = lib->l_libname; ln; ln = ln->next) {
lib_hash_delname (ln->name, lib);
}
}
/* Map in the shared object NAME, actually located in REALNAME, and already
opened on FD. */
@@ -801,7 +982,7 @@ lose (int code, int fd, const char *name, char *realname, struct link_map *l,
static
#endif
struct link_map *
_dl_map_object_from_fd (const char *name, const char *origname, int fd,
_dl_map_object_from_fd (const char *name, const char *origname, int fd, off_t offset,
struct filebuf *fbp, char *realname,
struct link_map *loader, int l_type, int mode,
void **stack_endp, Lmid_t nsid)
@@ -831,24 +1012,25 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
}
/* Look again to see if the real name matched another already loaded. */
for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next)
if (!l->l_removed && _dl_file_id_match_p (&l->l_file_id, &id))
{
/* The object is already loaded.
Just bump its reference count and return it. */
__close (fd);
l = lib_hash_getfile (nsid, id.dev, id.ino, offset);
if (l)
{
/* The object is already loaded.
Just bump its reference count and return it. */
__close_nocancel (fd);
/* If the name is not in the list of names for this object add
it. */
free (realname);
add_name_to_object (l, name);
free (realname);
return l;
}
return l;
}
#ifdef SHARED
/* When loading into a namespace other than the base one we must
avoid loading ld.so since there can only be one copy. Ever. */
/* Note that this test is wrong in two ways:
1) it doesn't consider offset, and
2) l_file_id.ino and l_file_id.dev for rtld are always zero! */
if (__glibc_unlikely (nsid != LM_ID_BASE)
&& (_dl_file_id_match_p (&id, &GL(dl_rtld_map).l_file_id)
|| _dl_name_match_p (name, &GL(dl_rtld_map))))
@@ -864,7 +1046,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
/* No need to bump the refcount of the real object, ld.so will
never be unloaded. */
__close (fd);
__close_nocancel (fd);
/* Add the map for the mirrored object to the object list. */
_dl_add_to_namespace_list (l, nsid);
@@ -878,7 +1060,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
/* We are not supposed to load the object unless it is already
loaded. So return now. */
free (realname);
__close (fd);
__close_nocancel (fd);
return NULL;
}
@@ -897,7 +1079,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
if (_dl_zerofd == -1)
{
free (realname);
__close (fd);
__close_nocancel (fd);
_dl_signal_error (errno, NULL, NULL,
N_("cannot open zero fill device"));
}
@@ -939,8 +1121,29 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
else
assert (r->r_state == RT_ADD);
#ifdef SHARED
// This code could be linked into 'sln', which does not have _itoa.
// We only care about this when this is linked into ld-linux.
if (offset != 0)
{
/* Google-specific: to help GDB, and for b/18243822, turn realname
into "realname/@0x<offset>" */
realname = realloc (realname, strlen(realname) + 16 + 4 /* "/@0x" */);
if (realname == NULL)
{
errstring = N_("unable to realloc");
goto call_lose_errno;
}
strcat(realname, "/@0x");
char tmp[20];
tmp[19] = '\0';
strcat(realname, _itoa(offset, &tmp[19], 16, 0));
}
#endif
/* Enter the new object in the list of loaded objects. */
l = _dl_new_object (realname, name, l_type, loader, mode, nsid);
l = _dl_new_object (realname, (offset ? realname : name), l_type, loader, mode, nsid);
if (__glibc_unlikely (l == NULL))
{
#ifdef SHARED
@@ -963,7 +1166,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
{
phdr = alloca (maplength);
__lseek (fd, header->e_phoff, SEEK_SET);
if ((size_t) __libc_read (fd, (void *) phdr, maplength) != maplength)
if ((size_t) __read_nocancel (fd, (void *) phdr, maplength) != maplength)
{
errstring = N_("cannot read file data");
goto call_lose_errno;
@@ -1027,7 +1230,12 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
c->mapend = ALIGN_UP (ph->p_vaddr + ph->p_filesz, GLRO(dl_pagesize));
c->dataend = ph->p_vaddr + ph->p_filesz;
c->allocend = ph->p_vaddr + ph->p_memsz;
c->mapoff = ALIGN_DOWN (ph->p_offset, GLRO(dl_pagesize));
if (offset & (GLRO(dl_pagesize) - 1))
{
errstring = N_("invalid offset");
goto call_lose;
}
c->mapoff = ALIGN_DOWN(offset + ph->p_offset, GLRO(dl_pagesize));
/* Determine whether there is a gap between the last segment
and this one. */
@@ -1239,7 +1447,7 @@ cannot enable executable stack as shared object requires");
l->l_tls_initimage = (char *) l->l_tls_initimage + l->l_addr;
/* We are done mapping in the file. We no longer need the descriptor. */
if (__glibc_unlikely (__close (fd) != 0))
if (__glibc_unlikely (__close_nocancel (fd) != 0))
{
errstring = N_("cannot close file descriptor");
goto call_lose_errno;
@@ -1307,10 +1515,9 @@ cannot enable executable stack as shared object requires");
assert (origname == NULL);
#endif
/* When we profile the SONAME might be needed for something else but
loading. Add it right away. */
if (__glibc_unlikely (GLRO(dl_profile) != NULL)
&& l->l_info[DT_SONAME] != NULL)
l->l_off = offset;
if (l->l_info[DT_SONAME] != NULL)
add_name_to_object (l, ((const char *) D_PTR (l, l_info[DT_STRTAB])
+ l->l_info[DT_SONAME]->d_un.d_val));
@@ -1392,7 +1599,7 @@ print_search_path (struct r_search_path_elem **list,
If FD is not -1, then the file is already open and FD refers to it.
In that case, FD is consumed for both successful and error returns. */
static int
open_verify (const char *name, int fd,
open_verify (const char *name, int fd, off_t offset,
struct filebuf *fbp, struct link_map *loader,
int whatcode, int mode, bool *found_other_class, bool free_name)
{
@@ -1454,7 +1661,7 @@ open_verify (const char *name, int fd,
{
/* An audit library changed what we're supposed to open,
so FD no longer matches it. */
__close (fd);
__close_nocancel (fd);
fd = -1;
}
}
@@ -1462,16 +1669,20 @@ open_verify (const char *name, int fd,
if (fd == -1)
/* Open the file. We always open files read-only. */
fd = __open (name, O_RDONLY | O_CLOEXEC);
fd = __open64_nocancel (name, O_RDONLY | O_CLOEXEC);
if (fd != -1)
{
ElfW(Ehdr) *ehdr;
ElfW(Phdr) *phdr, *ph;
ElfW(Word) *abi_note;
ElfW(Word) *abi_note_malloced = NULL;
unsigned int osversion;
size_t maplength;
if (__lseek (fd, offset, SEEK_SET) == -1)
goto close_and_out;
/* We successfully opened the file. Now verify it is a file
we can use. */
__set_errno (0);
@@ -1480,8 +1691,8 @@ open_verify (const char *name, int fd,
/* Read in the header. */
do
{
ssize_t retlen = __libc_read (fd, fbp->buf + fbp->len,
sizeof (fbp->buf) - fbp->len);
ssize_t retlen = __read_nocancel (fd, fbp->buf + fbp->len,
sizeof (fbp->buf) - fbp->len);
if (retlen <= 0)
break;
fbp->len += retlen;
@@ -1604,7 +1815,8 @@ open_verify (const char *name, int fd,
{
phdr = alloca (maplength);
__lseek (fd, ehdr->e_phoff, SEEK_SET);
if ((size_t) __libc_read (fd, (void *) phdr, maplength) != maplength)
if ((size_t) __read_nocancel (fd, (void *) phdr, maplength)
!= maplength)
{
read_error:
errval = errno;
@@ -1640,10 +1852,25 @@ open_verify (const char *name, int fd,
abi_note = (void *) (fbp->buf + ph->p_offset);
else
{
abi_note = alloca (size);
/* Note: __libc_use_alloca is not usable here, because
thread info may not have been set up yet. */
if (size < __MAX_ALLOCA_CUTOFF)
abi_note = alloca (size);
else
{
/* There could be multiple PT_NOTEs. */
abi_note_malloced = realloc (abi_note_malloced, size);
if (abi_note_malloced == NULL)
goto read_error;
abi_note = abi_note_malloced;
}
__lseek (fd, ph->p_offset, SEEK_SET);
if (__libc_read (fd, (void *) abi_note, size) != size)
goto read_error;
if (__read_nocancel (fd, (void *) abi_note, size) != size)
{
free (abi_note_malloced);
goto read_error;
}
}
while (memcmp (abi_note, &expected_note, sizeof (expected_note)))
@@ -1671,13 +1898,14 @@ open_verify (const char *name, int fd,
|| (GLRO(dl_osversion) && GLRO(dl_osversion) < osversion))
{
close_and_out:
__close (fd);
__close_nocancel (fd);
__set_errno (ENOENT);
fd = -1;
}
break;
}
free (abi_note_malloced);
}
return fd;
@@ -1691,7 +1919,7 @@ open_verify (const char *name, int fd,
if MAY_FREE_DIRS is true. */
static int
open_path (const char *name, size_t namelen, int mode,
open_path (const char *name, size_t namelen, off_t offset, int mode,
struct r_search_path_struct *sps, char **realname,
struct filebuf *fbp, struct link_map *loader, int whatcode,
bool *found_other_class)
@@ -1743,7 +1971,7 @@ open_path (const char *name, size_t namelen, int mode,
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
_dl_debug_printf (" trying file=%s\n", buf);
fd = open_verify (buf, -1, fbp, loader, whatcode, mode,
fd = open_verify (buf, -1, offset, fbp, loader, whatcode, mode,
found_other_class, false);
if (this_dir->status[cnt] == unknown)
{
@@ -1787,7 +2015,7 @@ open_path (const char *name, size_t namelen, int mode,
/* The shared object cannot be tested for being SUID
or this bit is not set. In this case we must not
use this object. */
__close (fd);
__close_nocancel (fd);
fd = -1;
/* We simply ignore the file, signal this by setting
the error value which would have been set by `open'. */
@@ -1808,7 +2036,7 @@ open_path (const char *name, size_t namelen, int mode,
{
/* No memory for the name, we certainly won't be able
to load and link it. */
__close (fd);
__close_nocancel (fd);
return -1;
}
}
@@ -1838,10 +2066,22 @@ open_path (const char *name, size_t namelen, int mode,
return -1;
}
static int
match_one (const char *name, struct link_map *l)
{
/* If the requested name matches the soname of a loaded object,
use that object. Elide this check for names that have not
yet been opened. */
if (__builtin_expect (l->l_faked, 0) != 0
|| __builtin_expect (l->l_removed, 0) != 0)
return 0;
return _dl_name_match_p (name, l);
}
/* Map in the shared object file NAME. */
struct link_map *
_dl_map_object (struct link_map *loader, const char *name,
_dl_map_object (struct link_map *loader, const char *name, off_t offset,
int type, int trace_mode, int mode, Lmid_t nsid)
{
int fd;
@@ -1855,33 +2095,21 @@ _dl_map_object (struct link_map *loader, const char *name,
assert (nsid < GL(dl_nns));
/* Look for this name among those already loaded. */
for (l = GL(dl_ns)[nsid]._ns_loaded; l; l = l->l_next)
if (name[0] == '\0')
{
/* If the requested name matches the soname of a loaded object,
use that object. Elide this check for names that have not
yet been opened. */
if (__glibc_unlikely ((l->l_faked | l->l_removed) != 0))
continue;
if (!_dl_name_match_p (name, l))
{
const char *soname;
/* Special case: both main exe and vdso can have empty name;
so search from head: it is important to return the map for main
a.out; else dlsym(0, ...) will fail unexpectedly. */
if (__glibc_likely (l->l_soname_added)
|| l->l_info[DT_SONAME] == NULL)
continue;
soname = ((const char *) D_PTR (l, l_info[DT_STRTAB])
+ l->l_info[DT_SONAME]->d_un.d_val);
if (strcmp (name, soname) != 0)
continue;
/* We have a match on a new name -- cache it. */
add_name_to_object (l, soname);
l->l_soname_added = 1;
}
/* We have a match. */
return l;
for (l = GL(dl_ns)[nsid]._ns_loaded; l; l = l->l_next)
if (match_one (name, l))
return l;
}
else
{
l = lib_hash_getname(nsid, name);
if (l)
return l;
}
/* Display information if we are debugging. */
@@ -1956,7 +2184,7 @@ _dl_map_object (struct link_map *loader, const char *name,
for (l = loader; l; l = l->l_loader)
if (cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH"))
{
fd = open_path (name, namelen, mode,
fd = open_path (name, namelen, offset, mode,
&l->l_rpath_dirs,
&realname, &fb, loader, LA_SER_RUNPATH,
&found_other_class);
@@ -1972,7 +2200,7 @@ _dl_map_object (struct link_map *loader, const char *name,
&& main_map != NULL && main_map->l_type != lt_loaded
&& cache_rpath (main_map, &main_map->l_rpath_dirs, DT_RPATH,
"RPATH"))
fd = open_path (name, namelen, mode,
fd = open_path (name, namelen, offset, mode,
&main_map->l_rpath_dirs,
&realname, &fb, loader ?: main_map, LA_SER_RUNPATH,
&found_other_class);
@@ -1980,7 +2208,7 @@ _dl_map_object (struct link_map *loader, const char *name,
/* Try the LD_LIBRARY_PATH environment variable. */
if (fd == -1 && env_path_list.dirs != (void *) -1)
fd = open_path (name, namelen, mode, &env_path_list,
fd = open_path (name, namelen, offset, mode, &env_path_list,
&realname, &fb,
loader ?: GL(dl_ns)[LM_ID_BASE]._ns_loaded,
LA_SER_LIBPATH, &found_other_class);
@@ -1989,7 +2217,7 @@ _dl_map_object (struct link_map *loader, const char *name,
if (fd == -1 && loader != NULL
&& cache_rpath (loader, &loader->l_runpath_dirs,
DT_RUNPATH, "RUNPATH"))
fd = open_path (name, namelen, mode,
fd = open_path (name, namelen, offset, mode,
&loader->l_runpath_dirs, &realname, &fb, loader,
LA_SER_RUNPATH, &found_other_class);
@@ -1998,7 +2226,7 @@ _dl_map_object (struct link_map *loader, const char *name,
realname = _dl_sysdep_open_object (name, namelen, &fd);
if (realname != NULL)
{
fd = open_verify (realname, fd,
fd = open_verify (realname, fd, offset,
&fb, loader ?: GL(dl_ns)[nsid]._ns_loaded,
LA_SER_CONFIG, mode, &found_other_class,
false);
@@ -2052,7 +2280,7 @@ _dl_map_object (struct link_map *loader, const char *name,
if (cached != NULL)
{
fd = open_verify (cached, -1,
fd = open_verify (cached, -1, 0,
&fb, loader ?: GL(dl_ns)[nsid]._ns_loaded,
LA_SER_CONFIG, mode, &found_other_class,
false);
@@ -2070,7 +2298,7 @@ _dl_map_object (struct link_map *loader, const char *name,
&& ((l = loader ?: GL(dl_ns)[nsid]._ns_loaded) == NULL
|| __glibc_likely (!(l->l_flags_1 & DF_1_NODEFLIB)))
&& rtld_search_dirs.dirs != (void *) -1)
fd = open_path (name, namelen, mode, &rtld_search_dirs,
fd = open_path (name, namelen, offset, mode, &rtld_search_dirs,
&realname, &fb, l, LA_SER_DEFAULT, &found_other_class);
/* Add another newline when we are tracing the library loading. */
@@ -2087,7 +2315,7 @@ _dl_map_object (struct link_map *loader, const char *name,
fd = -1;
else
{
fd = open_verify (realname, -1, &fb,
fd = open_verify (realname, -1, offset, &fb,
loader ?: GL(dl_ns)[nsid]._ns_loaded, 0, mode,
&found_other_class, true);
if (__glibc_unlikely (fd == -1))
@@ -2149,7 +2377,7 @@ _dl_map_object (struct link_map *loader, const char *name,
}
void *stack_end = __libc_stack_end;
return _dl_map_object_from_fd (name, origname, fd, &fb, realname, loader,
return _dl_map_object_from_fd (name, origname, fd, offset, &fb, realname, loader,
type, mode, &stack_end, nsid);
}
+352 -10
View File
@@ -25,6 +25,7 @@
#include <dl-hash.h>
#include <dl-machine.h>
#include <sysdep-cancel.h>
#include <hp-timing.h>
#include <libc-lock.h>
#include <tls.h>
#include <atomic.h>
@@ -39,6 +40,11 @@
#define VERSTAG(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag))
#ifndef ADDRIDX
# define ADDRIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \
+ DT_EXTRANUM + DT_VALNUM + DT_ADDRTAGIDX (tag))
#endif
struct sym_val
{
@@ -325,6 +331,326 @@ do_lookup_unique (const char *undef_name, uint_fast32_t new_hash,
result->m = (struct link_map *) map;
}
/* A hash table used to speed up lookups when we have a lot of shared
libraries. We record in the table how many ELF objects in the link
map we can safely skip, because they are known to not contain the symbol
we are looking for.
We go through each object (executable or DSO) in their order in the
main_map and insert pos_in_main_map into the table. Searches for
symbols not present in the table start at num_objects, skipping every
object preprocessed in this way.
If there is already an earlier (smaller) entry in the table, we leave it
alone. It represents an earlier instance of the same symbol (eg weak
__stdout definition in multiple objects). */
struct position_hash
{
/* The Bernstein hash, shifted right one bit. (This lets us build a table
directly from the precomputed values in DT_GNU_HASH sections, in which
the low bit is repurposed to terminate hash chains.) */
uint32_t hash;
/* The position of the first library with this symbol in the search list. */
uint32_t pos;
/* The symbol name. */
const char *name;
};
static struct position_hash *position_hash_table;
static size_t position_hash_table_slots;
static size_t position_hash_table_slots_occupied;
static int position_hash_lookup_default;
static int
position_hash_put (struct position_hash *table, size_t slots,
struct position_hash *item)
{
size_t mask = slots - 1;
/* Search for a matching entry or a free slot. This loop always terminates
because we don't allow the hashtable to become completely full. */
for (size_t stride = 0, i = item->hash; ; i += ++stride)
{
struct position_hash *slot = &table[i & mask];
if (slot->name == NULL)
{
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FASTLOAD, 0))
_dl_debug_printf ("fastload: put %s hash 0x%x pos %u slot 0x%lx\n",
item->name, item->hash, item->pos, slot - table);
slot->hash = item->hash;
slot->pos = item->pos;
slot->name = item->name;
return 1;
}
else if (slot->hash == item->hash &&
(slot->name == item->name || !strcmp (slot->name, item->name)))
{
if (item->pos < slot->pos)
slot->pos = item->pos;
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FASTLOAD, 0))
_dl_debug_printf ("fastload: dup %s hash 0x%x pos %u slot 0x%lx\n",
item->name, item->hash, slot->pos, slot - table);
return 0;
}
}
}
static void
position_hash_resize (struct position_hash *oldtable,
size_t oldslots, size_t newslots)
{
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FASTLOAD, 0))
_dl_debug_printf ("fastload: resizing hashtable to %lu slots\n", newslots);
assert (!oldtable == !oldslots);
void *ptr = mmap (NULL, newslots * sizeof *oldtable, PROT_READ|PROT_WRITE,
MAP_ANON|MAP_PRIVATE|MAP_POPULATE, -1, 0);
if (ptr == MAP_FAILED)
_dl_signal_error (errno, NULL, NULL, "cannot mmap fastload hashtable");
struct position_hash *newtable = position_hash_table = ptr;
position_hash_table_slots = newslots;
if (oldtable == NULL)
return;
for (size_t i = 0; i < oldslots; ++i)
{
if (oldtable[i].name)
position_hash_put (newtable, newslots, &oldtable[i]);
}
if (munmap (oldtable, oldslots * sizeof *oldtable))
_dl_signal_error (errno, NULL, NULL, "cannot munmap fastload hashtable");
}
static void
position_hash_init (int lookup_default)
{
assert (position_hash_table == NULL);
position_hash_lookup_default = lookup_default;
position_hash_resize (NULL, 0, 8192);
}
static void
position_hash_insert (uint32_t hash, const char *name, uint32_t pos)
{
struct position_hash *table = position_hash_table;
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FASTLOAD, 0))
_dl_debug_printf ("fastload: insert %s hash 0x%x pos %u\n", name, hash, pos);
size_t slots = position_hash_table_slots;
struct position_hash item = { hash, pos, name };
if (!position_hash_put (table, slots, &item))
return;
size_t newsize = ++position_hash_table_slots_occupied;
if (newsize >= slots / 2)
/* The load factor has reached 50%. Double the table size and rehash. */
position_hash_resize (table, slots, 2 * slots);
}
static int
position_hash_lookup (uint32_t hash, const char *name)
{
struct position_hash *table = position_hash_table;
if (table == NULL)
return 0;
size_t mask = position_hash_table_slots - 1;
for (size_t stride = 0, i = hash; ; i += ++stride)
{
struct position_hash *slot = &table[i & mask];
if (slot->hash == hash &&
(slot->name == name || !strcmp (slot->name, name)))
{
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FASTLOAD, 0))
_dl_debug_printf ("fastload: found %s at slot 0x%lx, pos %u\n",
name, slot - table, slot->pos);
return slot->pos;
}
else if (slot->name == NULL)
{
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FASTLOAD, 0))
_dl_debug_printf ("fastload: missed %s at slot 0x%lx, default pos %u\n",
name, slot - table, position_hash_lookup_default);
return position_hash_lookup_default;
}
}
}
static int
position_hash_include_symbol (const ElfW(Sym) *sym)
{
if (sym->st_value == 0 && ELFW(ST_TYPE) (sym->st_info) != STT_TLS)
return 0;
switch (ELFW(ST_TYPE) (sym->st_info))
{
case STT_SECTION:
case STT_FILE:
case STT_COMMON:
return 0;
}
/* Local symbols are ignored. */
return ELFW(ST_BIND) (sym->st_info) != STB_LOCAL;
}
static int
last_gnu_hash_bucket (const struct link_map *map)
{
/* The best documentation for GNU_HASH I found:
http://www.linker-aliens.org/blogs/ali/entry/gnu_hash_elf_sections/
_dl_setup_hash() has already set things up for us. */
if (__builtin_expect (map->l_nbuckets < 1, 0))
/* Paranoia: neither gold nor gnu-ld will construct an empty
.gnu.hash, but some other linker just might. */
return 0;
/* In the GNU hash the symbol index of a symbol is determined by
the offset of the symbol's entry in the hash table itself.
We start at the last bucket map->l_gnu_buckets[map->l_nbuckets-1]
and loop backward from the end until we find a bucket which is
not zero. */
int last_bucket_idx = map->l_nbuckets - 1;
while (last_bucket_idx > 0 &&
map->l_gnu_buckets[last_bucket_idx] == 0)
--last_bucket_idx;
return map->l_gnu_buckets[last_bucket_idx];
}
static void
position_hash_fill_from_gnu_hash (const struct link_map *map,
int pos_in_main_map)
{
int last_bucket = last_gnu_hash_bucket (map);
if (last_bucket == 0)
return;
/* Start of hash values. */
const Elf32_Word *chains = &map->l_gnu_buckets[map->l_nbuckets];
/* Reconstruct the number of symbols omitted. */
const Elf32_Word *zero = map->l_gnu_chain_zero;
int symbias = chains - zero;
const ElfW(Sym) *const symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]);
const char *const strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
/* Iterate through the symbols in the GNU hash chains and insert them
into the position hash table. If the symbol wouldn't pass the tests
in do_lookup_x(), then don't insert it. */
for (int k = symbias; ; ++k)
{
uint32_t hash = zero[k];
const ElfW(Sym) *sym = &symtab[k];
if (position_hash_include_symbol (sym))
position_hash_insert (hash >> 1, strtab + sym->st_name, pos_in_main_map);
/* Stop when we've passed the start of the last chain and the sentinel bit
terminating a chain is set. This is the end of the section. */
if (k >= last_bucket && (hash & 1))
break;
}
}
static int
old_hash_nchain (const struct link_map *map)
{
if (map->l_info[DT_HASH] == NULL)
return 0;
const Elf_Symndx *const hash = (void *) D_PTR (map, l_info[DT_HASH]);
if (hash == NULL)
return 0;
/* Read the "nchain" field of the DT_HASH section; see
https://refspecs.linuxfoundation.org/elf/gabi4+/ch5.dynamic.html#hash. */
return hash[1];
}
static void
position_hash_fill_from_symtab (const struct link_map *const map,
int pos_in_main_map)
{
const ElfW(Sym) *const symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]);
const char *const strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
const int num_symbols = old_hash_nchain (map);
/* Iterate through the symbols defined in this map and insert them
into the position hash table. If the symbol wouldn't pass the tests
in do_lookup_x(), then don't insert it. */
for (int k = 0; k < num_symbols; k++)
{
const ElfW(Sym) *sym = &symtab[k];
if (position_hash_include_symbol (sym))
{
uint32_t hash = dl_new_hash (strtab + sym->st_name);
position_hash_insert (hash >> 1, strtab + sym->st_name, pos_in_main_map);
}
}
}
/* Create the fastload position hash (if requested). Given a link_map
containing all required objects, iterate through all symbols. For each
symbol which could match in do_lookup_x, insert the index of the
providing object in main_map. */
void
_dl_fill_position_hash (struct link_map *main_map)
{
const int num_objects = main_map->l_searchlist.r_nlist;
const int debug_fastload = GLRO(dl_debug_mask) & DL_DEBUG_FASTLOAD;
int k;
/* If we have more than dl_position_hash_cutoff shared libraries,
fill in the hash table of earliest known positions for symbols in
main_map. We'll use this in do_lookup_x(). */
/* If cutoff is negative, fastload is disabled. */
if (GLRO(dl_position_hash_cutoff) < 0)
{
if (__builtin_expect (debug_fastload, 0))
_dl_debug_printf ("fastload: disabled (configuration)\n");
return;
}
/* If we don't have enough mapped objects, fastload is disabled. */
if (num_objects <= GLRO(dl_position_hash_cutoff))
{
if (__builtin_expect (debug_fastload, 0))
_dl_debug_printf ("fastload: disabled (too few objects,"
" %u <= cutoff %u)\n",
num_objects, GLRO(dl_position_hash_cutoff));
return;
}
int timing = (HP_TIMING_AVAIL) && (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS);
hp_timing_t start, stop, elapsed;
if (timing)
HP_TIMING_NOW (start);
position_hash_init (num_objects);
for (k = 0; k < num_objects; ++k)
{
const struct link_map *const map = main_map->l_searchlist.r_list[k];
if (map->l_info[ADDRIDX (DT_GNU_HASH)] != NULL)
position_hash_fill_from_gnu_hash (map, k);
else
position_hash_fill_from_symtab (map, k);
}
if (!timing)
return;
HP_TIMING_NOW (stop);
HP_TIMING_DIFF (elapsed, start, stop);
char buf[80];
HP_TIMING_PRINT (buf, sizeof buf, elapsed);
_dl_debug_printf ("\t time to build fastload table: %s\n", buf);
}
/* Inner part of the lookup functions. We return a value > 0 if we
found the symbol, the value 0 if nothing is found and < 0 if
something bad happened. */
@@ -344,6 +670,32 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
__asm volatile ("" : "+r" (n), "+m" (scope->r_list));
struct link_map **list = scope->r_list;
if (scope == GL(dl_ns)[LM_ID_BASE]._ns_main_searchlist && i == 0)
{
const int skip_to = position_hash_lookup (new_hash >> 1, undef_name);
if (skip_to < n)
{
i = skip_to;
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FASTLOAD, 0))
_dl_debug_printf ("fastload: lookup %s skipping to %u\n",
undef_name, (unsigned int) i);
}
else
{
/* Symbol was not found in any of the initial libraries,
and no new libraries have been added. */
assert (skip_to == n);
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FASTLOAD, 0))
_dl_debug_printf ("fastload: lookup %s, %u >= %u (scope->r_nlist)\n",
undef_name, (unsigned int) skip_to,
(unsigned int) n);
return 0;
}
}
do
{
const struct link_map *map = list[i]->l_real;
@@ -548,16 +900,6 @@ skip:
}
static uint_fast32_t
dl_new_hash (const char *s)
{
uint_fast32_t h = 5381;
for (unsigned char c = *s; c != '\0'; c = *++s)
h = h * 33 + c;
return h & 0xffffffff;
}
/* Add extra dependency on MAP to UNDEF_MAP. */
static int
add_dependency (struct link_map *undef_map, struct link_map *map, int flags)
+183 -11
View File
@@ -33,7 +33,7 @@
#include <sysdep.h>
#include <_itoa.h>
#include <dl-writev.h>
#include <not-cancel.h>
/* Read the whole contents of FILE into new mmap'd space with given
protections. *SIZEP gets the size of the file. On error MAP_FAILED
@@ -44,7 +44,7 @@ _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
{
void *result = MAP_FAILED;
struct stat64 st;
int fd = __open (file, O_RDONLY | O_CLOEXEC);
int fd = __open64_nocancel (file, O_RDONLY | O_CLOEXEC);
if (fd >= 0)
{
if (__fxstat64 (_STAT_VER, fd, &st) >= 0)
@@ -65,7 +65,7 @@ _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
#endif
, fd, 0);
}
__close (fd);
__close_nocancel (fd);
}
return result;
}
@@ -81,7 +81,10 @@ _dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg)
struct iovec iov[NIOVMAX];
int niov = 0;
pid_t pid = 0;
char pidbuf[12];
char pidbuf[23];
pid_t tid = 0;
/* Start with a known bad value, should never get used. */
char *tag_start = NULL;
while (*fmt != '\0')
{
@@ -93,20 +96,32 @@ _dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg)
colon followed by a tab. */
if (pid == 0)
{
char *p;
char *p = &pidbuf[21];
pid = __getpid ();
assert (pid >= 0 && sizeof (pid_t) <= 4);
p = _itoa (pid, &pidbuf[10], 10, 0);
while (p > pidbuf)
/* If we are doing thread-related output, maybe add a thread id,
taking care that pid continues to appear at the same
positions. */
tid = _dl_tls_tid ();
if (tid > 0)
{
p = _itoa (tid, p, 10, 0);
*--p = '/';
}
tag_start = p - 10;
p = _itoa (pid, p, 10, 0);
while (p > tag_start)
*--p = ' ';
pidbuf[10] = ':';
pidbuf[11] = '\t';
pidbuf[21] = ':';
pidbuf[22] = '\t';
}
/* Append to the output. */
assert (niov < NIOVMAX);
iov[niov].iov_len = 12;
iov[niov++].iov_base = pidbuf;
iov[niov].iov_len = &(pidbuf[23]) - tag_start;
iov[niov++].iov_base = tag_start;
/* No more tags until we see the next newline. */
tag_p = -1;
@@ -440,3 +455,160 @@ _dl_strtoul (const char *nptr, char **endptr)
return result;
}
/* To support accessing TLS variables from signal handlers, we need an
async signal safe memory allocator. These routines are never
themselves invoked reentrantly (all calls to them are surrounded by
signal masks) but may be invoked concurrently from many threads.
The current implementation is not particularly performant nor space
efficient, but it will be used rarely (and only in binaries that use
dlopen.) The API matches that of malloc() and friends. */
struct __signal_safe_allocator_header
{
size_t size;
void *start;
};
static inline struct __signal_safe_allocator_header *
ptr_to_signal_safe_allocator_header (void *ptr)
{
return (struct __signal_safe_allocator_header *)
((char *) (ptr) - sizeof (struct __signal_safe_allocator_header));
}
void *weak_function
__signal_safe_memalign (size_t boundary, size_t size)
{
struct __signal_safe_allocator_header *header;
if (boundary < sizeof (*header))
boundary = sizeof (*header);
/* Boundary must be a power of two. */
if (!powerof2 (boundary))
return NULL;
size_t pg = GLRO (dl_pagesize);
size_t padded_size;
if (boundary <= pg)
{
/* We'll get a pointer certainly aligned to boundary, so just
add one more boundary-sized chunk to hold the header. */
padded_size = roundup (size, boundary) + boundary;
}
else
{
/* If we want K pages aligned to a J-page boundary, K+J+1 pages
contains at least one such region that isn't directly at the start
(so we can place the header.) This is wasteful, but you're the one
who wanted 64K-aligned TLS. */
padded_size = roundup (size, pg) + boundary + pg;
}
size_t actual_size = roundup (padded_size, pg);
void *actual = mmap (NULL, actual_size, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (actual == MAP_FAILED)
return NULL;
if (boundary <= pg)
{
header = actual + boundary - sizeof (*header);
}
else
{
intptr_t actual_pg = ((intptr_t) actual) / pg;
intptr_t boundary_pg = boundary / pg;
intptr_t start_pg = actual_pg + boundary_pg;
start_pg -= start_pg % boundary_pg;
if (start_pg > (actual_pg + 1))
{
int ret = munmap (actual, (start_pg - actual_pg - 1) * pg);
assert (ret == 0);
actual = (void *) ((start_pg - 1) * pg);
}
char *start = (void *) (start_pg * pg);
header = ptr_to_signal_safe_allocator_header (start);
}
header->size = actual_size;
header->start = actual;
void *ptr = header;
ptr += sizeof (*header);
if (((intptr_t) ptr) % boundary != 0)
_dl_fatal_printf ("__signal_safe_memalign produced incorrect alignment\n");
return ptr;
}
void * weak_function
__signal_safe_malloc (size_t size)
{
if (!GLRO(dl_async_signal_safe))
return malloc (size);
return __signal_safe_memalign (1, size);
}
void weak_function
__signal_safe_free (void *ptr)
{
if (!GLRO(dl_async_signal_safe))
{
free (ptr);
return;
}
if (ptr == NULL)
return;
struct __signal_safe_allocator_header *header
= ptr_to_signal_safe_allocator_header (ptr);
int ret = munmap (header->start, header->size);
assert (ret == 0);
}
void * weak_function
__signal_safe_realloc (void *ptr, size_t size)
{
if (!GLRO(dl_async_signal_safe))
return realloc (ptr, size);
if (size == 0)
{
__signal_safe_free (ptr);
return NULL;
}
if (ptr == NULL)
return __signal_safe_malloc (size);
struct __signal_safe_allocator_header *header
= ptr_to_signal_safe_allocator_header (ptr);
size_t old_size = header->size;
if (old_size - sizeof (*header) >= size)
return ptr;
void *new_ptr = __signal_safe_malloc (size);
if (new_ptr == NULL)
return NULL;
/* Copy over the old block (but not its header). */
memcpy (new_ptr, ptr, old_size - sizeof (*header));
__signal_safe_free (ptr);
return new_ptr;
}
void * weak_function
__signal_safe_calloc (size_t nmemb, size_t size)
{
if (!GLRO(dl_async_signal_safe))
return calloc (nmemb, size);
void *ptr = __signal_safe_malloc (nmemb * size);
if (ptr == NULL)
return NULL;
return memset (ptr, 0, nmemb * size);
}
+4 -5
View File
@@ -34,9 +34,7 @@ _dl_add_to_namespace_list (struct link_map *new, Lmid_t nsid)
if (GL(dl_ns)[nsid]._ns_loaded != NULL)
{
struct link_map *l = GL(dl_ns)[nsid]._ns_loaded;
while (l->l_next != NULL)
l = l->l_next;
struct link_map *l = _dl_last_entry (&GL(dl_ns)[nsid]);
new->l_prev = l;
/* new->l_next = NULL; Would be necessary but we use calloc. */
l->l_next = new;
@@ -47,12 +45,13 @@ _dl_add_to_namespace_list (struct link_map *new, Lmid_t nsid)
new->l_serial = GL(dl_load_adds);
++GL(dl_load_adds);
_dl_hash_add_object (new);
__rtld_lock_unlock_recursive (GL(dl_load_write_lock));
}
/* Allocate a `struct link_map' for a new object being loaded,
and enter it into the _dl_loaded list. */
/* Allocate a `struct link_map' for a new object being loaded. */
struct link_map *
_dl_new_object (char *realname, const char *libname, int type,
struct link_map *loader, int mode, Lmid_t nsid)
+9 -3
View File
@@ -44,6 +44,8 @@
struct dl_open_args
{
const char *file;
/* ELF header at offset in file. */
off_t offset;
int mode;
/* This is the caller of the dlopen() function. */
const void *caller_dlopen;
@@ -221,7 +223,7 @@ dl_open_worker (void *a)
/* Load the named object. */
struct link_map *new;
args->map = new = _dl_map_object (call_map, file, lt_loaded, 0,
args->map = new = _dl_map_object (call_map, file, args->offset, lt_loaded, 0,
mode | __RTLD_CALLMAP, args->nsid);
/* If the pointer returned is NULL this means the RTLD_NOLOAD flag is
@@ -493,7 +495,10 @@ TLS generation counter wrapped! Please report this."));
generation of the DSO we are allocating data for. */
_dl_update_slotinfo (imap->l_tls_modid);
#endif
/* We do this iteration under a signal mask in dl-reloc; why not
here? Because these symbols are new and dlopen hasn't
returned yet. So we can't possibly be racing with a TLS
access to them from another thread. */
GL(dl_init_static_tls) (imap);
assert (imap->l_need_tls_init == 0);
}
@@ -531,7 +536,7 @@ TLS generation counter wrapped! Please report this."));
void *
_dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid,
_dl_open (const char *file, off_t offset, int mode, const void *caller_dlopen, Lmid_t nsid,
int argc, char *argv[], char *env[])
{
if ((mode & RTLD_BINDING_MASK) == 0)
@@ -581,6 +586,7 @@ no more namespaces available for dlmopen()"));
struct dl_open_args args;
args.file = file;
args.offset = offset;
args.mode = mode;
args.caller_dlopen = caller_dlopen;
args.caller_dl_open = RETURN_ADDRESS (0);
+7 -7
View File
@@ -35,6 +35,7 @@
#include <sys/param.h>
#include <sys/stat.h>
#include <atomic.h>
#include <not-cancel.h>
/* The LD_PROFILE feature has to be implemented different to the
normal profiling using the gmon/ functions. The problem is that an
@@ -324,7 +325,7 @@ _dl_start_profile (void)
*cp++ = '/';
__stpcpy (__stpcpy (cp, GLRO(dl_profile)), ".profile");
fd = __open (filename, O_RDWR | O_CREAT | O_NOFOLLOW, DEFFILEMODE);
fd = __open64_nocancel (filename, O_RDWR|O_CREAT|O_NOFOLLOW, DEFFILEMODE);
if (fd == -1)
{
char buf[400];
@@ -335,7 +336,7 @@ _dl_start_profile (void)
print_error:
errnum = errno;
if (fd != -1)
__close (fd);
__close_nocancel (fd);
_dl_error_printf (errstr, filename,
__strerror_r (errnum, buf, sizeof buf));
return;
@@ -364,15 +365,14 @@ _dl_start_profile (void)
goto print_error;
}
if (TEMP_FAILURE_RETRY (__libc_write (fd, buf, (expected_size
& (GLRO(dl_pagesize)
- 1))))
if (TEMP_FAILURE_RETRY
(__write_nocancel (fd, buf, (expected_size & (GLRO(dl_pagesize) - 1))))
< 0)
goto cannot_create;
}
else if (st.st_size != expected_size)
{
__close (fd);
__close_nocancel (fd);
wrong_format:
if (addr != NULL)
@@ -392,7 +392,7 @@ _dl_start_profile (void)
}
/* We don't need the file descriptor anymore. */
__close (fd);
__close_nocancel (fd);
/* Pointer to data after the header. */
hist = (char *) (addr + 1);
+14 -2
View File
@@ -19,7 +19,13 @@
#if ENABLE_STATIC_PIE
#include <unistd.h>
#include <ldsodefs.h>
#include "dynamic-link.h"
#ifndef NESTING
# define STATIC_PIE_BOOTSTRAP
# define BOOTSTRAP_MAP (main_map)
# define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP
# include "dynamic-link.h"
#endif /* n NESTING */
/* Relocate static executable with PIE. */
@@ -28,10 +34,12 @@ _dl_relocate_static_pie (void)
{
struct link_map *main_map = _dl_get_dl_main_map ();
#ifdef NESTING
# define STATIC_PIE_BOOTSTRAP
# define BOOTSTRAP_MAP (main_map)
# define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP
# include "dynamic-link.h"
#endif /* NESTING */
/* Figure out the run-time load address of static PIE. */
main_map->l_addr = elf_machine_load_address ();
@@ -46,7 +54,11 @@ _dl_relocate_static_pie (void)
/* Relocate ourselves so we can do normal function calls and
data access using the global offset table. */
ELF_DYNAMIC_RELOCATE (main_map, 0, 0, 0);
ELF_DYNAMIC_RELOCATE (main_map, 0, 0, 0
#ifndef NESTING
, main_map
#endif
);
main_map->l_relocated = 1;
}
#endif
+105 -7
View File
@@ -16,8 +16,10 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <atomic.h>
#include <errno.h>
#include <libintl.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <ldsodefs.h>
@@ -71,7 +73,8 @@ _dl_try_allocate_static_tls (struct link_map *map)
size_t offset = GL(dl_tls_static_used) + (freebytes - n * map->l_tls_align
- map->l_tls_firstbyte_offset);
map->l_tls_offset = GL(dl_tls_static_used) = offset;
if (!GLRO(dl_async_signal_safe))
map->l_tls_offset = GL(dl_tls_static_used) = offset;
#elif TLS_DTV_AT_TP
/* dl_tls_static_used includes the TCB at the beginning. */
size_t offset = (ALIGN_UP(GL(dl_tls_static_used)
@@ -83,12 +86,48 @@ _dl_try_allocate_static_tls (struct link_map *map)
if (used > GL(dl_tls_static_size))
goto fail;
map->l_tls_offset = offset;
map->l_tls_firstbyte_offset = GL(dl_tls_static_used);
GL(dl_tls_static_used) = used;
if (!GLRO(dl_async_signal_safe)) {
map->l_tls_offset = offset;
map->l_tls_firstbyte_offset = GL(dl_tls_static_used);
GL(dl_tls_static_used) = used;
}
#else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif
if (GLRO(dl_async_signal_safe)) {
/* We've computed the new value we want, now try to install it. */
ptrdiff_t val;
if ((val = map->l_tls_offset) == NO_TLS_OFFSET)
{
/* l_tls_offset starts out at NO_TLS_OFFSET, and all attempts to
change it go from NO_TLS_OFFSET to some other value. We use
compare_and_exchange to ensure only one attempt succeeds. We
don't actually need any memory ordering here, but _acq is the
weakest available. */
(void ) atomic_compare_and_exchange_bool_acq (&map->l_tls_offset,
offset,
NO_TLS_OFFSET);
val = map->l_tls_offset;
assert (val != NO_TLS_OFFSET);
}
if (val != offset)
{
/* We'd like to set a static offset for this section, but another
thread has already used a dynamic TLS block for it. Since we can
only use static offsets if everyone does (and it's not practical
to move that thread's dynamic block), we have to fail. */
goto fail;
}
/* We installed the value; now update the globals. */
#if TLS_TCB_AT_TP // second
GL(dl_tls_static_used) = offset;
#elif TLS_DTV_AT_TP // second
map->l_tls_firstbyte_offset = GL(dl_tls_static_used);
GL(dl_tls_static_used) = used;
#else // second
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" // second
#endif // second
}
/* If the object is not yet relocated we cannot initialize the
static TLS region. Delay it. */
@@ -114,8 +153,19 @@ void
__attribute_noinline__
_dl_allocate_static_tls (struct link_map *map)
{
if (map->l_tls_offset == FORCED_DYNAMIC_TLS_OFFSET
|| _dl_try_allocate_static_tls (map))
/* We wrap this in a signal mask because it has to iterate all threads
(including this one) and update this map's TLS entry. A signal handler
accessing TLS would try to do the same update and break. */
sigset_t old;
if (GLRO(dl_async_signal_safe))
_dl_mask_all_signals (&old);
int err = -1;
if (map->l_tls_offset != FORCED_DYNAMIC_TLS_OFFSET)
err = _dl_try_allocate_static_tls (map);
if (GLRO(dl_async_signal_safe))
_dl_unmask_signals (&old);
if (err != 0)
{
_dl_signal_error (0, map->l_name, NULL, N_("\
cannot allocate memory in static TLS block"));
@@ -141,6 +191,40 @@ _dl_nothread_init_static_tls (struct link_map *map)
'\0', map->l_tls_blocksize - map->l_tls_initimage_size);
}
#ifndef NESTING
/* String table object symbols. */
static struct link_map *glob_l;
static struct r_scope_elem **glob_scope;
static const char *glob_strtab;
/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */
#define RESOLVE_MAP(ref, version, r_type) \
((ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL \
&& __glibc_likely (!dl_symbol_visibility_binds_local_p (*ref))) \
? ((__builtin_expect ((*ref) == glob_l->l_lookup_cache.sym, 0) \
&& elf_machine_type_class (r_type) == glob_l->l_lookup_cache.type_class) \
? (bump_num_cache_relocations (), \
(*ref) = glob_l->l_lookup_cache.ret, \
glob_l->l_lookup_cache.value) \
: ({ lookup_t _lr; \
int _tc = elf_machine_type_class (r_type); \
glob_l->l_lookup_cache.type_class = _tc; \
glob_l->l_lookup_cache.sym = (*ref); \
const struct r_found_version *v = NULL; \
if ((version) != NULL && (version)->hash != 0) \
v = (version); \
_lr = _dl_lookup_symbol_x (glob_strtab + (*ref)->st_name, glob_l, (ref), \
glob_scope, v, _tc, \
DL_LOOKUP_ADD_DEPENDENCY, NULL); \
glob_l->l_lookup_cache.ret = (*ref); \
glob_l->l_lookup_cache.value = _lr; })) \
: glob_l)
#include "dynamic-link.h"
#endif /* n NESTING */
void
_dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
@@ -227,6 +311,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
{
/* Do the actual relocation of the object's GOT and other data. */
#ifdef NESTING
/* String table object symbols. */
const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
@@ -255,7 +341,19 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
#include "dynamic-link.h"
ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling, skip_ifunc);
#else
glob_l = l;
glob_scope = scope;
glob_strtab = (const void *) D_PTR (glob_l, l_info[DT_STRTAB]);
#endif /* NESTING */
ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling, skip_ifunc
#ifndef NESTING
, NULL
#endif
);
#ifndef PROF
if (__glibc_unlikely (consider_profiling)
+24 -3
View File
@@ -33,11 +33,32 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used,
unsigned int i = 0;
uint16_t seen[nmaps];
memset (seen, 0, nmaps * sizeof (seen[0]));
while (1)
/* Mark objects with in-edges. */
for (unsigned j = i; j < nmaps; ++j)
maps[j]->l_inedge = 0;
for (unsigned j = i; j < nmaps; ++j)
{
for (struct link_map **p = maps[j]->l_initfini; p && *p; ++p)
{
if (*p != maps[j]) /* Skip self-edges. */
(*p)->l_inedge = 1;
}
}
while (i < nmaps)
{
struct link_map *thisp = maps[i];
if (!thisp->l_inedge)
{
/* No dependencies on this object. */
++i;
continue;
}
/* Keep track of which object we looked at this round. */
++seen[i];
struct link_map *thisp = maps[i];
if (__glibc_unlikely (for_fini))
{
@@ -52,7 +73,7 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used,
with the dependency. */
unsigned int k = nmaps - 1;
while (k > i)
{
{
struct link_map **runp = maps[k]->l_initfini;
if (runp != NULL)
/* Look through the dependencies of the object. */
+9
View File
@@ -67,9 +67,15 @@ void *__libc_stack_end;
/* Path where the binary is found. */
const char *_dl_origin_path;
/* Directory where the AT_EXECFN is found. */
const char *_google_exec_origin_dir;
/* Nonzero if runtime lookup should not update the .got/.plt. */
int _dl_bind_not;
/* Nonzero if TLS handling should be async-signal-safe. */
int _dl_async_signal_safe;
/* A dummy link map for the executable, used by dlopen to access the global
scope. We don't export any symbols ourselves, so this can be minimal. */
static struct link_map _dl_main_map =
@@ -136,6 +142,9 @@ hp_timing_t _dl_cpuclock_offset;
void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
/* The merged position hash table used if we have a lot of shared objects. */
int _dl_position_hash_cutoff = DL_POSITION_HASH_CUTOFF_DEFAULT;
size_t _dl_pagesize = EXEC_PAGESIZE;
int _dl_inhibit_cache;
+300 -7
View File
@@ -17,6 +17,7 @@
<http://www.gnu.org/licenses/>. */
#include <assert.h>
#include <atomic.h>
#include <errno.h>
#include <libintl.h>
#include <signal.h>
@@ -29,6 +30,8 @@
#include <dl-tls.h>
#include <ldsodefs.h>
static void _dl_print_dtv(const char *msg, dtv_t *dtv, int numentries);
/* Amount of excess space to allocate in the static TLS area
to allow dynamic loading of modules defining IE-model TLS data. */
#define TLS_STATIC_SURPLUS 64 + DL_NNS * 100
@@ -283,7 +286,7 @@ allocate_dtv (void *result)
initial set of modules. This should avoid in most cases expansions
of the dtv. */
dtv_length = GL(dl_tls_max_dtv_idx) + DTV_SURPLUS;
dtv = calloc (dtv_length + 2, sizeof (dtv_t));
dtv = __signal_safe_calloc (dtv_length + 2, sizeof (dtv_t));
if (dtv != NULL)
{
/* This is the initial length of the dtv. */
@@ -408,14 +411,14 @@ _dl_resize_dtv (dtv_t *dtv)
dl-minimal.c malloc instead of the real malloc. We can't free
it, we have to abandon the old storage. */
newp = malloc ((2 + newsize) * sizeof (dtv_t));
newp = __signal_safe_malloc ((2 + newsize) * sizeof (dtv_t));
if (newp == NULL)
oom ();
memcpy (newp, &dtv[-1], (2 + oldsize) * sizeof (dtv_t));
}
else
{
newp = realloc (&dtv[-1],
newp = __signal_safe_realloc (&dtv[-1],
(2 + newsize) * sizeof (dtv_t));
if (newp == NULL)
oom ();
@@ -427,6 +430,13 @@ _dl_resize_dtv (dtv_t *dtv)
memset (newp + 2 + oldsize, '\0',
(newsize - oldsize) * sizeof (dtv_t));
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_TLS))
_dl_debug_printf ("Resized dtv 0x%0*Zx, size %lu, to dtv 0x%0*Zx, size %lu\n",
(int) sizeof (void *) * 2, (unsigned long int) dtv,
oldsize,
(int) sizeof (void *) * 2, (unsigned long int) &newp[1],
newsize);
/* Return the generation counter. */
return &newp[1];
}
@@ -483,6 +493,12 @@ _dl_allocate_tls_init (void *result)
dtv[map->l_tls_modid].pointer.val = TLS_DTV_UNALLOCATED;
dtv[map->l_tls_modid].pointer.to_free = NULL;
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_TLS))
_dl_debug_printf ("_dl_allocate_tls_init unallocates %sdtv 0x%0*Zx module %lu\n",
(dtv == THREAD_DTV () ? "own " : ""),
(int) sizeof (void *) * 2,
(unsigned long int) dtv,
map->l_tls_modid);
if (map->l_tls_offset == NO_TLS_OFFSET
|| map->l_tls_offset == FORCED_DYNAMIC_TLS_OFFSET)
@@ -502,6 +518,14 @@ _dl_allocate_tls_init (void *result)
/* Set up the DTV entry. The simplified __tls_get_addr that
some platforms use in static programs requires it. */
dtv[map->l_tls_modid].pointer.val = dest;
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_TLS))
_dl_debug_printf ("_dl_allocate_tls_init sets %sdtv 0x%0*Zx module %lu to 0x%0*Zx\n",
(dtv == THREAD_DTV () ? "own " : ""),
(int) sizeof (void *) * 2,
(unsigned long int) dtv,
map->l_tls_modid,
(int) sizeof (void *) * 2,
(unsigned long int) dest);
/* Copy the initialization image and clear the BSS part. */
memset (__mempcpy (dest, map->l_tls_initimage,
@@ -520,6 +544,9 @@ _dl_allocate_tls_init (void *result)
/* The DTV version is up-to-date now. */
dtv[0].counter = maxgen;
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_TLS))
_dl_print_dtv ("_dl_allocate_tls_init return ", dtv, 10);
return result;
}
rtld_hidden_def (_dl_allocate_tls_init)
@@ -533,6 +560,19 @@ _dl_allocate_tls (void *mem)
}
rtld_hidden_def (_dl_allocate_tls)
/* Clear the given dtv. (We have this here because __signal_safe_free is
not visible to nptl/allocatestack.c.) */
void
_dl_clear_dtv (dtv_t *dtv)
{
for (size_t cnt = 0; cnt < dtv[-1].counter; ++cnt)
__signal_safe_free (dtv[1 + cnt].pointer.to_free);
memset (dtv, '\0', (dtv[-1].counter + 1) * sizeof (dtv_t));
}
rtld_hidden_def (_dl_clear_dtv)
void
_dl_deallocate_tls (void *tcb, bool dealloc_tcb)
@@ -541,11 +581,11 @@ _dl_deallocate_tls (void *tcb, bool dealloc_tcb)
/* We need to free the memory allocated for non-static TLS. */
for (size_t cnt = 0; cnt < dtv[-1].counter; ++cnt)
free (dtv[1 + cnt].pointer.to_free);
__signal_safe_free (dtv[1 + cnt].pointer.to_free);
/* The array starts with dtv[-1]. */
if (dtv != GL(dl_initial_dtv))
free (dtv - 1);
__signal_safe_free (dtv - 1);
if (dealloc_tcb)
free (*tcb_to_pointer_to_free_location (tcb));
@@ -617,6 +657,24 @@ allocate_and_init (struct link_map *map)
return result;
}
static void
signal_safe_allocate_and_init (dtv_t *dtv, struct link_map *map)
{
void *newp;
newp = __signal_safe_memalign (map->l_tls_align, map->l_tls_blocksize);
if (newp == NULL)
oom ();
/* Initialize the memory. Since this is our thread's space, we are
under a signal mask, and no one has touched this section before,
we can safely just overwrite whatever's there. */
memset (__mempcpy (newp, map->l_tls_initimage,
map->l_tls_initimage_size),
'\0', map->l_tls_blocksize - map->l_tls_initimage_size);
dtv->pointer.val = newp;
dtv->pointer.to_free = newp;
}
struct link_map *
_dl_update_slotinfo (unsigned long int req_modid)
@@ -624,6 +682,12 @@ _dl_update_slotinfo (unsigned long int req_modid)
struct link_map *the_map = NULL;
dtv_t *dtv = THREAD_DTV ();
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_TLS))
// (should mention module name?)
_dl_debug_printf ("Updating slot info for own dtv 0x%0*Zx module %lu\n",
(int) sizeof (void *) * 2, (unsigned long int) dtv,
req_modid);
/* The global dl_tls_dtv_slotinfo array contains for each module
index the generation counter current when the entry was created.
This array never shrinks so that all module indices which were
@@ -656,7 +720,25 @@ _dl_update_slotinfo (unsigned long int req_modid)
the entry we need. */
size_t new_gen = listp->slotinfo[idx].gen;
size_t total = 0;
sigset_t old;
if (GLRO(dl_async_signal_safe)) {
_dl_mask_all_signals (&old);
/* We use the signal mask as a lock against reentrancy here.
Check that a signal taken before the lock didn't already
update us. */
dtv = THREAD_DTV ();
if (dtv[0].counter >= listp->slotinfo[idx].gen)
{
_dl_unmask_signals (&old);
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_TLS))
_dl_debug_printf ("Slot info update for own dtv 0x%0*Zx module %lu done, exiting early\n",
(int) sizeof (void *) * 2,
(unsigned long int) dtv,
req_modid);
return the_map;
}
}
/* We have to look through the entire dtv slotinfo list. */
listp = GL(dl_tls_dtv_slotinfo_list);
do
@@ -684,7 +766,14 @@ _dl_update_slotinfo (unsigned long int req_modid)
{
/* If this modid was used at some point the memory
might still be allocated. */
free (dtv[total + cnt].pointer.to_free);
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_TLS))
_dl_debug_printf ("Slot info update for own dtv 0x%0*Zx module %lu unallocating 0x%0*Zx\n",
(int) sizeof (void *) * 2,
(unsigned long int) dtv,
total + cnt,
(int) sizeof (void *) * 2,
(unsigned long int) dtv[total + cnt].pointer.val);
__signal_safe_free (dtv[total + cnt].pointer.to_free);
dtv[total + cnt].pointer.val = TLS_DTV_UNALLOCATED;
dtv[total + cnt].pointer.to_free = NULL;
}
@@ -711,7 +800,14 @@ _dl_update_slotinfo (unsigned long int req_modid)
dtv entry free it. */
/* XXX Ideally we will at some point create a memory
pool. */
free (dtv[modid].pointer.to_free);
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_TLS))
_dl_debug_printf ("Slot info update for own dtv 0x%0*Zx module %lu unallocating 0x%0*Zx\n",
(int) sizeof (void *) * 2,
(unsigned long int) dtv,
modid,
(int) sizeof (void *) * 2,
(unsigned long int) dtv[modid].pointer.val);
__signal_safe_free (dtv[modid].pointer.to_free);
dtv[modid].pointer.val = TLS_DTV_UNALLOCATED;
dtv[modid].pointer.to_free = NULL;
@@ -725,6 +821,8 @@ _dl_update_slotinfo (unsigned long int req_modid)
/* This will be the new maximum generation counter. */
dtv[0].counter = new_gen;
if (GLRO(dl_async_signal_safe))
_dl_unmask_signals (&old);
}
return the_map;
@@ -750,6 +848,17 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
the_map = listp->slotinfo[idx].map;
}
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_TLS))
{
char *map_name = (the_map->l_name ? the_map->l_name : "no name");
_dl_debug_printf ("tls_get_addr_tail entry, own dtv 0x%0*Zx module %lu (%s) pointer.val = 0x%0*Zx\n",
(int) sizeof (void *) * 2, (unsigned long int) dtv,
GET_ADDR_MODULE, map_name,
(int) sizeof (void *) * 2,
(unsigned long int) dtv[GET_ADDR_MODULE].pointer.val);
}
if (!GLRO(dl_async_signal_safe)) {
/* Make sure that, if a dlopen running in parallel forces the
variable into static storage, we'll wait until the address in the
@@ -778,6 +887,13 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
dtv[GET_ADDR_MODULE].pointer.to_free = NULL;
dtv[GET_ADDR_MODULE].pointer.val = p;
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_TLS))
_dl_debug_printf ("tls_get_addr_tail sets own dtv 0x%0*Zx module %lu pointer.val to 0x%0*Zx, returns\n",
(int) sizeof (void *) * 2,
(unsigned long int) dtv,
GET_ADDR_MODULE,
(int) sizeof (void *) * 2,
(unsigned long int) p);
return (char *) p + GET_ADDR_OFFSET;
}
@@ -787,8 +903,120 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
struct dtv_pointer result = allocate_and_init (the_map);
dtv[GET_ADDR_MODULE].pointer = result;
assert (result.to_free != NULL);
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_TLS))
_dl_debug_printf ("tls_get_addr_tail sets own dtv 0x%0*Zx module %lu pointer.val to 0x%0*Zx, returns\n",
(int) sizeof (void *) * 2, (unsigned long int) dtv,
GET_ADDR_MODULE,
(int) sizeof (void *) * 2, (unsigned long int) result.val);
return (char *) result.val + GET_ADDR_OFFSET;
} else {
sigset_t old;
_dl_mask_all_signals (&old);
/* As with update_slotinfo, we use the sigmask as a check against
reentrancy. */
if (dtv[GET_ADDR_MODULE].pointer.val != TLS_DTV_UNALLOCATED)
{
_dl_unmask_signals (&old);
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_TLS))
_dl_debug_printf ("tls_get_addr_tail keeps own dtv pointer.val, returns\n");
return (char *) dtv[GET_ADDR_MODULE].pointer.val + GET_ADDR_OFFSET;
}
/* Synchronize against a parallel dlopen() forcing this variable
into static storage. If that happens, we have to be more careful
about initializing the area, as that dlopen() will be iterating
the threads to do so itself. */
ptrdiff_t offset = the_map->l_tls_offset;
if (offset == NO_TLS_OFFSET)
{
/* l_tls_offset starts out at NO_TLS_OFFSET, and all attempts to
change it go from NO_TLS_OFFSET to some other value. We use
compare_and_exchange to ensure only one attempt succeeds. We
don't actually need any memory ordering here, but _acq is the
weakest available. */
(void) atomic_compare_and_exchange_bool_acq (&the_map->l_tls_offset,
FORCED_DYNAMIC_TLS_OFFSET,
NO_TLS_OFFSET);
offset = the_map->l_tls_offset;
assert (offset != NO_TLS_OFFSET);
}
if (offset == FORCED_DYNAMIC_TLS_OFFSET)
{
signal_safe_allocate_and_init (&dtv[GET_ADDR_MODULE], the_map);
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_TLS))
_dl_debug_printf ("tls_get_addr_tail allocates own dtv 0x%0*Zx module %lu pointer.val = 0x%0*Zx\n",
(int) sizeof (void *) * 2,
(unsigned long int) dtv,
GET_ADDR_MODULE,
(int) sizeof (void *) * 2,
(unsigned long int) dtv[GET_ADDR_MODULE].pointer.val);
}
/* It can happen that slot info updates will un-allocate a pointer (possibly
due to a bug elsewhere), which leaves us waiting indefinitely for the
dlopen that will never happen. Emulate the async-signal-unsafe case above
and use a static TLS address. */
else if (dtv[GET_ADDR_MODULE].pointer.val == TLS_DTV_UNALLOCATED)
{
#if TLS_TCB_AT_TP
void *p = (char *) THREAD_SELF - the_map->l_tls_offset;
#elif TLS_DTV_AT_TP
void *p = (char *) THREAD_SELF + the_map->l_tls_offset + TLS_PRE_TCB_SIZE;
#else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif
dtv[GET_ADDR_MODULE].pointer.to_free = NULL;
dtv[GET_ADDR_MODULE].pointer.val = p;
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_TLS))
_dl_debug_printf ("tls_get_addr_tail sets unallocated own dtv 0x%0*Zx module %lu pointer.val = 0x%0*Zx\n",
(int) sizeof (void *) * 2,
(unsigned long int) dtv,
GET_ADDR_MODULE,
(int) sizeof (void *) * 2,
(unsigned long int) dtv[GET_ADDR_MODULE].pointer.val);
}
else
{
void ** volatile pp = &dtv[GET_ADDR_MODULE].pointer.val;
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_TLS))
_dl_debug_printf ("tls_get_addr_tail waiting for own dtv 0x%0*Zx module %lu to be allocated\n",
(int) sizeof (void *) * 2,
(unsigned long int) dtv,
GET_ADDR_MODULE);
while (atomic_forced_read (*pp) == TLS_DTV_UNALLOCATED)
{
/* for lack of a better (safe) thing to do, just spin.
Someone else (not us; it's done under a signal mask) set
this map to a static TLS offset, and they'll iterate all
threads to initialize it. They'll eventually write
to pointer.val, at which point we know they've fully
completed initialization. */
atomic_spin_nop ();
}
/* Make sure we've picked up their initialization of the actual
block; this pairs against the write barrier in
init_one_static_tls, guaranteeing that we see their write of
the tls_initimage into the static region. */
atomic_read_barrier ();
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_TLS))
_dl_debug_printf ("tls_get_addr_tail sees own dtv 0x%0*Zx module %lu has pointer.val = 0x%0*Zx\n",
(int) sizeof (void *) * 2,
(unsigned long int) dtv,
GET_ADDR_MODULE,
(int) sizeof (void *) * 2,
(unsigned long int) dtv[GET_ADDR_MODULE].pointer.val);
}
assert (dtv[GET_ADDR_MODULE].pointer.val != TLS_DTV_UNALLOCATED);
_dl_unmask_signals (&old);
return (char *) dtv[GET_ADDR_MODULE].pointer.val + GET_ADDR_OFFSET;
}
}
@@ -942,3 +1170,68 @@ cannot create TLS data structures"));
listp->slotinfo[idx].map = l;
listp->slotinfo[idx].gen = GL(dl_tls_generation) + 1;
}
/* Return a thread id of the current thread if we are debugging tls and the
value is meaningful. */
pid_t
_dl_tls_tid (void)
{
if (!__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_TLS))
return 0;
#ifdef SHARED
if (GL(dl_initial_dtv) == NULL)
return 0;
#endif
struct pthread *thr = THREAD_SELF;
return thr->tid;
}
/* Print all or part of a dtv. Note that the output may be large; for instance
nptl/tst-stack4 has dtv's with hundreds of entries. */
static void
_dl_print_dtv (const char *msg, dtv_t *dtv, int numentries)
{
size_t cnt, last_used, num_to_print, i;
cnt = dtv[-1].counter;
last_used = 0;
for (i = 1; i <= cnt; ++i)
{
if (dtv[i].pointer.val || dtv[i].pointer.to_free)
last_used = i;
}
num_to_print = last_used;
if (numentries >= 0 && numentries < num_to_print)
num_to_print = numentries;
_dl_debug_printf ("%sdtv 0x%0*Zx has %lu used of %lu entries, generation %lu\n",
msg,
(int) sizeof (void *) * 2, (unsigned long int) dtv,
last_used, cnt, dtv[0].counter);
for (i = 1; i <= num_to_print; ++i)
{
if (dtv[i].pointer.to_free == dtv[i].pointer.val)
_dl_debug_printf ("%*lu: pointer.val = 0x%0*Zx to_free = same\n",
4, i,
(int) sizeof (void *) * 2,
(unsigned long int) dtv[i].pointer.val);
else if (dtv[i].pointer.to_free)
_dl_debug_printf ("%*lu: pointer.val = 0x%0*Zx to_free = 0x%0*Zx\n",
4, i,
(int) sizeof (void *) * 2,
(unsigned long int) dtv[i].pointer.val,
(int) sizeof (void *) * 2,
(unsigned long int) dtv[i].pointer.to_free);
else
_dl_debug_printf ("%*lu: pointer.val = 0x%0*Zx\n",
4, i,
(int) sizeof (void *) * 2,
(unsigned long int) dtv[i].pointer.val);
}
if (num_to_print < last_used)
_dl_debug_printf (" [...]\n");
}
+17 -4
View File
@@ -34,10 +34,23 @@ find_needed (const char *name, struct link_map *map)
struct link_map *tmap;
unsigned int n;
for (tmap = GL(dl_ns)[map->l_ns]._ns_loaded; tmap != NULL;
tmap = tmap->l_next)
if (_dl_name_match_p (name, tmap))
return tmap;
if (name[0] == '\0')
{
/* Special case: both main exe and vdso can have empty name;
so search from head: it is important to return the map for main
a.out; else dlsym(0, ...) will fail unexpectedly. */
for (tmap = GL(dl_ns)[map->l_ns]._ns_loaded; tmap != NULL;
tmap = tmap->l_next)
if (_dl_name_match_p (name, tmap))
return tmap;
}
else
{
for (tmap = _dl_last_entry (&GL(dl_ns)[map->l_ns]); tmap != NULL;
tmap = tmap->l_prev)
if (_dl_name_match_p (name, tmap))
return tmap;
}
/* The required object is not in the global scope, look to see if it is
a dependency of the current object. */
+25 -5
View File
@@ -41,7 +41,11 @@ auto inline void __attribute__ ((always_inline))
elf_dynamic_do_Rel (struct link_map *map,
ElfW(Addr) reladdr, ElfW(Addr) relsize,
__typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative,
int lazy, int skip_ifunc)
int lazy, int skip_ifunc
#ifndef NESTING
, struct link_map *boot_map
#endif
)
{
const ElfW(Rel) *r = (const void *) reladdr;
const ElfW(Rel) *end = (const void *) (reladdr + relsize);
@@ -136,7 +140,11 @@ elf_dynamic_do_Rel (struct link_map *map,
ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)],
&map->l_versions[ndx],
(void *) (l_addr + r->r_offset), skip_ifunc);
(void *) (l_addr + r->r_offset), skip_ifunc
#ifndef NESTING
, boot_map
#endif
);
}
#if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP
@@ -150,7 +158,11 @@ elf_dynamic_do_Rel (struct link_map *map,
&symtab[ELFW(R_SYM) (r2->r_info)],
&map->l_versions[ndx],
(void *) (l_addr + r2->r_offset),
skip_ifunc);
skip_ifunc
#ifndef NESTING
, boot_map
#endif
);
}
#endif
}
@@ -168,7 +180,11 @@ elf_dynamic_do_Rel (struct link_map *map,
else
# endif
elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
(void *) (l_addr + r->r_offset), skip_ifunc);
(void *) (l_addr + r->r_offset), skip_ifunc
#ifndef NESTING
, boot_map
#endif
);
# ifdef ELF_MACHINE_IRELATIVE
if (r2 != NULL)
@@ -176,7 +192,11 @@ elf_dynamic_do_Rel (struct link_map *map,
if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE)
elf_machine_rel (map, r2, &symtab[ELFW(R_SYM) (r2->r_info)],
NULL, (void *) (l_addr + r2->r_offset),
skip_ifunc);
skip_ifunc
#ifndef NESTING
, boot_map
#endif
);
# endif
}
#endif
+133 -1
View File
@@ -16,6 +16,10 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef NESTING
#define auto static
#endif
/* This macro is used as a callback from elf_machine_rel{a,} when a
static TLS reloc is about to be performed. Since (in dl-load.c) we
permit dynamic loading of objects that might use such relocs, we
@@ -70,7 +74,11 @@ elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
auto inline void __attribute__((always_inline))
elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
const ElfW(Sym) *sym, const struct r_found_version *version,
void *const reloc_addr, int skip_ifunc);
void *const reloc_addr, int skip_ifunc
#ifndef NESTING
, struct link_map *boot_map
#endif
);
auto inline void __attribute__((always_inline))
elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
void *const reloc_addr);
@@ -113,6 +121,64 @@ elf_machine_lazy_rel (struct link_map *map,
consumes precisely the very end of the DT_REL*, or DT_JMPREL and DT_REL*
are completely separate and there is a gap between them. */
#ifndef NESTING
# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel, boot_map) \
do { \
struct { ElfW(Addr) start, size; \
__typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative; int lazy; } \
ranges[2] = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; \
\
/* With DT_RELR, DT_RELA/DT_REL can have zero value. */ \
if ((map)->l_info[DT_##RELOC] != NULL \
&& (map)->l_info[DT_##RELOC]->d_un.d_ptr != 0) \
{ \
ranges[0].start = D_PTR ((map), l_info[DT_##RELOC]); \
ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val; \
if (map->l_info[VERSYMIDX (DT_##RELOC##COUNT)] != NULL) \
ranges[0].nrelative \
= map->l_info[VERSYMIDX (DT_##RELOC##COUNT)]->d_un.d_val; \
} \
if ((map)->l_info[DT_PLTREL] \
&& (!test_rel || (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)) \
{ \
ElfW(Addr) start = D_PTR ((map), l_info[DT_JMPREL]); \
ElfW(Addr) size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \
\
if (ranges[0].start == 0) \
ranges[0].start = start; \
if (ranges[0].start + ranges[0].size == (start + size)) \
ranges[0].size -= size; \
if (ELF_DURING_STARTUP \
|| (!(do_lazy) \
&& (ranges[0].start + ranges[0].size) == start)) \
{ \
/* Combine processing the sections. */ \
ranges[0].size += size; \
} \
else \
{ \
ranges[1].start = start; \
ranges[1].size = size; \
ranges[1].lazy = (do_lazy); \
} \
} \
\
if (ELF_DURING_STARTUP) \
elf_dynamic_do_##reloc ((map), ranges[0].start, ranges[0].size, \
ranges[0].nrelative, 0, skip_ifunc, boot_map); \
else \
{ \
int ranges_index; \
for (ranges_index = 0; ranges_index < 2; ++ranges_index) \
elf_dynamic_do_##reloc ((map), \
ranges[ranges_index].start, \
ranges[ranges_index].size, \
ranges[ranges_index].nrelative, \
ranges[ranges_index].lazy, \
skip_ifunc, boot_map); \
} \
} while (0)
#else /* NESTING */
# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel) \
do { \
struct { ElfW(Addr) start, size; \
@@ -165,6 +231,7 @@ elf_machine_lazy_rel (struct link_map *map,
skip_ifunc); \
} \
} while (0)
#endif /* NESTING */
# if ELF_MACHINE_NO_REL || ELF_MACHINE_NO_RELA
# define _ELF_CHECK_REL 0
@@ -172,6 +239,70 @@ elf_machine_lazy_rel (struct link_map *map,
# define _ELF_CHECK_REL 1
# endif
#ifndef NESTING
# if ! ELF_MACHINE_NO_REL
# include "do-rel.h"
# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc, boot_map) \
_ELF_DYNAMIC_DO_RELOC (REL, Rel, map, lazy, skip_ifunc, _ELF_CHECK_REL, boot_map)
# else
# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc, boot_map) /* Nothing to do. */
# endif
# if ! ELF_MACHINE_NO_RELA
# define DO_RELA
# include "do-rel.h"
# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc, boot_map) \
_ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, lazy, skip_ifunc, _ELF_CHECK_REL, boot_map)
# else
# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc, boot_map) /* Nothing to do. */
# endif
/* Google-local: b/208156916. To not bump DT_NUM, use DT_VERSYM+1 for DT_RELR
and DT_VERSYM+2 for DT_RELRSZ. */
# define ELF_DYNAMIC_DO_RELR(map) \
do { \
ElfW(Addr) l_addr = (map)->l_addr, *where = 0; \
const ElfW(Relr) *r, *end; \
if (!(map)->l_info[VERSYMIDX (DT_VERSYM + 1)]) \
break; \
r = (const ElfW(Relr) *)D_PTR((map), l_info[VERSYMIDX (DT_VERSYM + 1)]); \
end = (const ElfW(Relr) *)((const char *)r + \
(map)->l_info[VERSYMIDX (DT_VERSYM + 2)]->d_un.d_val); \
for (; r < end; r++) \
{ \
ElfW(Relr) entry = *r; \
if ((entry & 1) == 0) \
{ \
where = (ElfW(Addr) *)(l_addr + entry); \
*where++ += l_addr; \
} \
else \
{ \
for (long i = 0; (entry >>= 1) != 0; i++) \
if ((entry & 1) != 0) \
where[i] += l_addr; \
where += CHAR_BIT * sizeof(ElfW(Relr)) - 1; \
} \
} \
} while (0);
/* This can't just be an inline function because GCC is too dumb
to inline functions containing inlines themselves. */
# ifdef RTLD_BOOTSTRAP
# define DO_RTLD_BOOTSTRAP 1
# else
# define DO_RTLD_BOOTSTRAP 0
# endif
# define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile, skip_ifunc, boot_map) \
do { \
int edr_lazy = elf_machine_runtime_setup ((map), (lazy), \
(consider_profile)); \
if (((map) != &GL(dl_rtld_map) || DO_RTLD_BOOTSTRAP)) \
ELF_DYNAMIC_DO_RELR (map); \
ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc, boot_map); \
ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc, boot_map); \
} while (0)
#else /* NESTING */
# if ! ELF_MACHINE_NO_REL
# include "do-rel.h"
# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) \
@@ -198,5 +329,6 @@ elf_machine_lazy_rel (struct link_map *map,
ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc); \
ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc); \
} while (0)
#endif /* NESTING */
#endif
+13 -2
View File
@@ -444,8 +444,9 @@ typedef struct
#define SHT_FINI_ARRAY 15 /* Array of destructors */
#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
#define SHT_GROUP 17 /* Section group */
#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
#define SHT_NUM 19 /* Number of defined types. */
#define SHT_SYMTAB_SHNDX 18 /* Extended section indices */
#define SHT_RELR 19 /* RELR relative relocations */
#define SHT_NUM 20 /* Number of defined types. */
#define SHT_LOOS 0x60000000 /* Start OS-specific. */
#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */
#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */
@@ -663,6 +664,11 @@ typedef struct
Elf64_Sxword r_addend; /* Addend */
} Elf64_Rela;
/* RELR relocation table entry */
typedef Elf32_Word Elf32_Relr;
typedef Elf64_Xword Elf64_Relr;
/* How to extract and insert information held in the r_info field. */
#define ELF32_R_SYM(val) ((val) >> 8)
@@ -861,6 +867,11 @@ typedef struct
#define DT_ENCODING 32 /* Start of encoded range */
#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/
#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */
#define DT_SYMTAB_SHNDX 34 /* Address of SYMTAB_SHNDX section */
#define DT_RELRSZ 35 /* Total size of RELR relative relocations */
#define DT_RELR 36 /* Address of RELR relative relocations */
#define DT_RELRENT 37 /* Size of one RELR relative relocaction */
/* Google-local: b/208156916. Don't bump DT_NUM. */
#define DT_NUM 34 /* Number used */
#define DT_LOOS 0x6000000d /* Start of OS-specific */
#define DT_HIOS 0x6ffff000 /* End of OS-specific */
+31 -5
View File
@@ -22,6 +22,8 @@
#include <assert.h>
#include <libc-diag.h>
#if defined NESTING || !defined SAW_EGDI
#ifndef RESOLVE_MAP
static
#else
@@ -47,7 +49,12 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
while (dyn->d_tag != DT_NULL)
{
if ((d_tag_utype) dyn->d_tag < DT_NUM)
/* Google-local: b/208156916. See ELF_DYNAMIC_DO_RELR. */
if (dyn->d_tag == DT_RELR)
info[VERSYMIDX (DT_VERSYM + 1)] = dyn;
else if (dyn->d_tag == DT_RELRSZ)
info[VERSYMIDX (DT_VERSYM + 2)] = dyn;
else if ((d_tag_utype) dyn->d_tag < DT_NUM)
info[dyn->d_tag] = dyn;
else if (dyn->d_tag >= DT_LOPROC &&
dyn->d_tag < DT_LOPROC + DT_THISPROCNUM)
@@ -102,16 +109,27 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
ADJUST_DYN_INFO (DT_PLTGOT);
ADJUST_DYN_INFO (DT_STRTAB);
ADJUST_DYN_INFO (DT_SYMTAB);
ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM + 1)); /* DT_RELR */
ADJUST_DYN_INFO (DT_JMPREL);
ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
ADJUST_DYN_INFO (DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM + DT_THISPROCNUM
+ DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM);
# undef ADJUST_DYN_INFO
/* DT_RELA/DT_REL are mandatory. But they may have zero value if
there is DT_RELR. Don't relocate them if they are zero. */
# define ADJUST_DYN_INFO(tag) \
do \
if (info[tag] != NULL && info[tag]->d_un.d_ptr != 0) \
info[tag]->d_un.d_ptr += l_addr; \
while (0)
# if ! ELF_MACHINE_NO_RELA
ADJUST_DYN_INFO (DT_RELA);
# endif
# if ! ELF_MACHINE_NO_REL
ADJUST_DYN_INFO (DT_REL);
# endif
ADJUST_DYN_INFO (DT_JMPREL);
ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
ADJUST_DYN_INFO (DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM + DT_THISPROCNUM
+ DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM);
# undef ADJUST_DYN_INFO
assert (cnt <= DL_RO_DYN_TEMP_CNT);
}
@@ -184,3 +202,11 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
info[DT_RPATH] = NULL;
#endif
}
#endif
#ifndef NESTING
#ifndef SAW_EGDI
#define SAW_EGDI
#endif
#endif /* n NESTING */
+4 -4
View File
@@ -34,6 +34,8 @@
#include <bits/elfclass.h> /* Defines __ELF_NATIVE_CLASS. */
#include <bits/link.h>
__BEGIN_DECLS
/* Rendezvous structure used by the run-time dynamic linker to communicate
details of shared object loading to the debugger. If the executable's
dynamic section has a DT_DEBUG element, the run-time linker sets that
@@ -162,8 +164,6 @@ struct dl_phdr_info
void *dlpi_tls_data;
};
__BEGIN_DECLS
extern int dl_iterate_phdr (int (*__callback) (struct dl_phdr_info *,
size_t, void *),
void *__data);
@@ -187,8 +187,8 @@ extern uintptr_t la_symbind64 (Elf64_Sym *__sym, unsigned int __ndx,
unsigned int *__flags, const char *__symname);
extern unsigned int la_objclose (uintptr_t *__cookie);
__END_DECLS
#endif
__END_DECLS
#endif /* link.h */
+185 -16
View File
@@ -41,6 +41,7 @@
#include <tls.h>
#include <stap-probe.h>
#include <stackinfo.h>
#include <not-cancel.h>
#include <assert.h>
@@ -51,6 +52,12 @@ extern __typeof (__mempcpy) __mempcpy attribute_hidden;
extern __typeof (_exit) exit_internal asm ("_exit") attribute_hidden;
#define _exit exit_internal
/* Iterate over auxv, find AT_EXECFN if any. */
static char * get_at_execfn(ElfW(auxv_t) *auxv);
/* Given file path, return fully resolved directory path. */
static char * get_directory (const char *file_path);
/* Helper function to handle errors while resolving symbols. */
static void print_unresolved (int errcode, const char *objname,
const char *errsting);
@@ -73,6 +80,9 @@ enum mode { normal, list, verify, trace };
all the entries. */
static void process_envvars (enum mode *modep);
/* Set GLRO(google_exec_origin_dir). */
static void set_exec_origin_dir(const char *exe_path);
#ifdef DL_ARGV_NOT_RELRO
int _dl_argc attribute_hidden;
char **_dl_argv = NULL;
@@ -282,6 +292,7 @@ struct rtld_global_ro _rtld_global_ro attribute_relro =
._dl_open = _dl_open,
._dl_close = _dl_close,
._dl_tls_get_addr_soft = _dl_tls_get_addr_soft,
._dl_position_hash_cutoff = DL_POSITION_HASH_CUTOFF_DEFAULT,
#ifdef HAVE_DL_DISCOVER_OSVERSION
._dl_discover_osversion = _dl_discover_osversion
#endif
@@ -439,9 +450,30 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
return start_addr;
}
#ifndef NESTING
#ifdef DONT_USE_BOOTSTRAP_MAP
# define bootstrap_map GL(dl_rtld_map)
#else
# define bootstrap_map info.l
#endif
/* This #define produces dynamic linking inline functions for
bootstrap relocation instead of general-purpose relocation.
Since ld.so must not have any undefined symbols the result
is trivial: always the map of ld.so itself. */
#define RTLD_BOOTSTRAP
#define RESOLVE_MAP(sym, version, flags) (&bootstrap_map)
#include "dynamic-link.h"
#endif /* n NESTING */
static ElfW(Addr) __attribute_used__
_dl_start (void *arg)
{
#ifndef NESTING
#ifndef DONT_USE_BOOTSTRAP_MAP
struct dl_start_final_info info;
#endif /* DUBM */
#else /* NESTING */
#ifdef DONT_USE_BOOTSTRAP_MAP
# define bootstrap_map GL(dl_rtld_map)
#else
@@ -457,6 +489,7 @@ _dl_start (void *arg)
#define BOOTSTRAP_MAP (&bootstrap_map)
#define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP
#include "dynamic-link.h"
#endif /* NESTING */
if (HP_TIMING_INLINE && HP_SMALL_TIMING_AVAIL)
#ifdef DONT_USE_BOOTSTRAP_MAP
@@ -502,7 +535,11 @@ _dl_start (void *arg)
/* Relocate ourselves so we can do normal function calls and
data access using the global offset table. */
ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0, 0);
ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0, 0
#ifndef NESTING
, &bootstrap_map
#endif
);
}
bootstrap_map.l_relocated = 1;
@@ -588,7 +625,7 @@ map_doit (void *a)
{
struct map_args *args = (struct map_args *) a;
int type = (args->mode == __RTLD_OPENEXEC) ? lt_executable : lt_library;
args->map = _dl_map_object (args->loader, args->str, type, 0,
args->map = _dl_map_object (args->loader, args->str, 0, type, 0,
args->mode, LM_ID_BASE);
}
@@ -596,7 +633,7 @@ static void
dlmopen_doit (void *a)
{
struct dlmopen_args *args = (struct dlmopen_args *) a;
args->map = _dl_open (args->fname,
args->map = _dl_open (args->fname, 0,
(RTLD_LAZY | __RTLD_DLOPEN | __RTLD_AUDIT
| __RTLD_SECURE),
dl_main, LM_ID_NEWLM, _dl_argc, _dl_argv,
@@ -1007,6 +1044,8 @@ of this helper program; chances are you did not intend to run this program.\n\
in LIST\n\
--audit LIST use objects named in LIST as auditors\n");
set_exec_origin_dir (_dl_argv[1]);
++_dl_skip_args;
--_dl_argc;
++_dl_argv;
@@ -1050,7 +1089,7 @@ of this helper program; chances are you did not intend to run this program.\n\
else
{
HP_TIMING_NOW (start);
_dl_map_object (NULL, rtld_progname, lt_executable, 0,
_dl_map_object (NULL, rtld_progname, 0, lt_executable, 0,
__RTLD_OPENEXEC, LM_ID_BASE);
HP_TIMING_NOW (stop);
@@ -1101,6 +1140,8 @@ of this helper program; chances are you did not intend to run this program.\n\
}
else
{
set_exec_origin_dir (get_at_execfn (auxv));
/* Create a link_map for the executable itself.
This will be what dlopen on "" returns. */
main_map = _dl_new_object ((char *) "", "", lt_executable, NULL,
@@ -1335,6 +1376,7 @@ of this helper program; chances are you did not intend to run this program.\n\
GL(dl_rtld_map).l_type = lt_library;
main_map->l_next = &GL(dl_rtld_map);
GL(dl_rtld_map).l_prev = main_map;
_dl_hash_add_object (&GL(dl_rtld_map));
++GL(dl_ns)[LM_ID_BASE]._ns_nloaded;
++GL(dl_load_adds);
@@ -1344,21 +1386,16 @@ of this helper program; chances are you did not intend to run this program.\n\
if (GLRO(dl_use_load_bias) == (ElfW(Addr)) -2)
GLRO(dl_use_load_bias) = main_map->l_addr == 0 ? -1 : 0;
/* Set up the program header information for the dynamic linker
itself. It is needed in the dl_iterate_phdr callbacks. */
const ElfW(Ehdr) *rtld_ehdr;
/* Starting from binutils-2.23, the linker will define the magic symbol
__ehdr_start to point to our own ELF header if it is visible in a
segment that also includes the phdrs. If that's not available, we use
the old method that assumes the beginning of the file is part of the
lowest-addressed PT_LOAD segment. */
#ifdef HAVE_EHDR_START
extern const ElfW(Ehdr) __ehdr_start __attribute__ ((visibility ("hidden")));
rtld_ehdr = &__ehdr_start;
#else
rtld_ehdr = (void *) GL(dl_rtld_map).l_map_start;
#endif
/* Set up the program header information for the dynamic linker
itself. It is needed in the dl_iterate_phdr callbacks. */
const ElfW(Ehdr) *rtld_ehdr = &__ehdr_start;
assert (rtld_ehdr->e_ehsize == sizeof *rtld_ehdr);
assert (rtld_ehdr->e_phentsize == sizeof (ElfW(Phdr)));
@@ -1722,6 +1759,11 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
dependencies in the executable's searchlist for symbol resolution. */
HP_TIMING_NOW (start);
_dl_map_object_deps (main_map, preloads, npreloads, mode == trace, 0);
/* We have now finished loading every required (linked-in) object.
Set up the position hash if needed. */
_dl_fill_position_hash (main_map);
HP_TIMING_NOW (stop);
HP_TIMING_DIFF (diff, start, stop);
HP_TIMING_ACCUM_NT (load_time, diff);
@@ -2349,10 +2391,14 @@ process_dl_debug (const char *dl_debug)
DL_DEBUG_VERSIONS | DL_DEBUG_IMPCALLS },
{ LEN_AND_STR ("scopes"), "display scope information",
DL_DEBUG_SCOPES },
{ LEN_AND_STR ("tls"), "display thread-local storage processing",
DL_DEBUG_TLS },
{ LEN_AND_STR ("fastload"), "display fastload information",
DL_DEBUG_FASTLOAD },
{ LEN_AND_STR ("all"), "all previous options combined",
DL_DEBUG_LIBS | DL_DEBUG_RELOC | DL_DEBUG_FILES | DL_DEBUG_SYMBOLS
| DL_DEBUG_BINDINGS | DL_DEBUG_VERSIONS | DL_DEBUG_IMPCALLS
| DL_DEBUG_SCOPES },
| DL_DEBUG_SCOPES | DL_DEBUG_FASTLOAD },
{ LEN_AND_STR ("statistics"), "display relocation statistics",
DL_DEBUG_STATISTICS },
{ LEN_AND_STR ("unused"), "determined unused DSOs",
@@ -2464,6 +2510,9 @@ process_envvars (enum mode *modep)
enum mode mode = normal;
char *debug_output = NULL;
/* Enable async-signal-safe TLS by default. */
GLRO(dl_async_signal_safe) = 1;
/* This is the default place for profiling data file. */
GLRO(dl_profile_output)
= &"/var/tmp\0/var/profile"[__libc_enable_secure ? 9 : 0];
@@ -2487,6 +2536,10 @@ process_envvars (enum mode *modep)
/* Warning level, verbose or not. */
if (memcmp (envline, "WARN", 4) == 0)
GLRO(dl_verbose) = envline[5] != '\0';
#if 0 /* enable to get runtime control over async signal safety */
if (memcmp (envline, "SAFE", 4) == 0)
GLRO(dl_async_signal_safe) = 1;
#endif
break;
case 5:
@@ -2499,7 +2552,12 @@ process_envvars (enum mode *modep)
if (memcmp (envline, "AUDIT", 5) == 0)
audit_list_string = &envline[6];
break;
#if 0 /* enable to get runtime control over async signal safety */
case 6:
if (memcmp (envline, "UNSAFE", 6) == 0)
GLRO(dl_async_signal_safe) = 0;
break;
#endif
case 7:
/* Print information about versions. */
if (memcmp (envline, "VERBOSE", 7) == 0)
@@ -2623,11 +2681,36 @@ process_envvars (enum mode *modep)
EXTRA_LD_ENVVARS
#endif
}
/* Handle all fastload-related env vars here. This may duplicate
effort with the switch table above, but it localizes changes
made by the fastload patch. On Linux, the '15' case is used
by another environment variable (LIBRARY_VERSION) and much
change would be needed to add support adding a variable of
that length with the existing style. */
switch (len)
{
case 15:
if (memcmp (envline, "FASTLOAD_CUTOFF", 15) == 0)
GLRO(dl_position_hash_cutoff)
= _dl_strtoul (&envline[16], NULL);;
break;
}
}
/* The caller wants this information. */
*modep = mode;
#if 0 /* enable this to help debug async-safe TLS */
if (GLRO(dl_debug_mask))
{
if (GLRO(dl_async_signal_safe))
_dl_printf ("TLS is async-signal-safe\n");
else
_dl_printf ("TLS is NOT async-signal-safe\n");
}
#endif /* for async-safe TLS */
/* Extra security for SUID binaries. Remove all dangerous environment
variables. */
if (__builtin_expect (__libc_enable_secure, 0))
@@ -2674,7 +2757,7 @@ process_envvars (enum mode *modep)
*--startp = '.';
startp = memcpy (startp - name_len, debug_output, name_len);
GLRO(dl_debug_fd) = __open (startp, flags, DEFFILEMODE);
GLRO(dl_debug_fd) = __open64_nocancel (startp, flags, DEFFILEMODE);
if (GLRO(dl_debug_fd) == -1)
/* We use standard output if opening the file failed. */
GLRO(dl_debug_fd) = STDOUT_FILENO;
@@ -2785,3 +2868,89 @@ print_statistics (hp_timing_t *rtld_total_timep)
}
#endif
}
/* Given file path, return an absolute directory path.
Examples: in: "/foo/bar/a.out", out: "/foo/bar/";
in: "./a.out", out: "/dot/resolved/to/full/path/./". */
static char *
get_directory (const char *file_path)
{
assert (file_path != NULL);
/* Find the end of the directory substring in file_path. */
size_t path_len = strlen (file_path);
while (path_len > 0 && file_path[path_len - 1] != '/')
--path_len;
/* Allocate space and set the path prefix according to whether or not
this is an absolute path. */
char *dest;
char *full_dir_path;
if (file_path[0] == '/')
{
full_dir_path = malloc (path_len + 1);
assert (full_dir_path != NULL);
dest = full_dir_path;
}
else
{
/* For a relative path, we need to include space for the largest
possible current path, a joining '/', the relevant part of
file_path, and a trailing '\0'. */
full_dir_path = malloc (PATH_MAX + path_len + 2);
assert (full_dir_path != NULL);
char *status = __getcwd (full_dir_path, PATH_MAX);
assert (status != NULL);
dest = __rawmemchr (full_dir_path, '\0');
if (dest[-1] != '/')
*dest++ = '/';
}
if (path_len > 0)
dest = __mempcpy (dest, file_path, path_len);
*dest = '\0';
return full_dir_path;
}
/* Set GLRO(google_exec_origin_dir). */
static void
set_exec_origin_dir (const char *exe_path)
{
assert (GLRO(google_exec_origin_dir) == NULL);
if (GLRO(dl_origin_path) != NULL)
GLRO(google_exec_origin_dir) = strdup (GLRO(dl_origin_path));
else if (exe_path != NULL)
GLRO(google_exec_origin_dir) = get_directory (exe_path);
}
/* Iterate over auxv, find AT_EXECFN if any. */
static char *
get_at_execfn (ElfW(auxv_t) *auxv)
{
assert (auxv != NULL);
for (; auxv->a_type != AT_NULL; ++auxv)
if (auxv->a_type == AT_EXECFN)
return (char *) auxv->a_un.a_val;
return NULL;
}
#ifndef NESTING
char *dummy1 = (char *)elf_get_dynamic_info;
# if ! ELF_MACHINE_NO_REL
char *dummy2 = (char *)elf_machine_rel;
char *dummy3 = (char *)elf_machine_rel_relative;
#endif
# if ! ELF_MACHINE_NO_RELA
char *dummy4 = (char *)elf_machine_rela;
char *dummy5 = (char *)elf_machine_rela_relative;
#endif
# if ELF_MACHINE_NO_RELA || defined ELF_MACHINE_PLT_REL
char *dummy6 = (char *)elf_machine_lazy_rel;
#endif
#endif
-25
View File
@@ -1,25 +0,0 @@
/* Macros to support TLS testing in times of missing compiler support. */
#define COMMON_INT_DEF(x) \
asm (".tls_common " #x ",4,4")
/* XXX Until we get compiler support we don't need declarations. */
#define COMMON_INT_DECL(x)
/* XXX This definition will probably be machine specific, too. */
#define VAR_INT_DEF(x) \
asm (".section .tdata\n\t" \
".globl " #x "\n" \
".balign 4\n" \
#x ":\t.long 0\n\t" \
".size " #x ",4\n\t" \
".previous")
/* XXX Until we get compiler support we don't need declarations. */
#define VAR_INT_DECL(x)
#include_next <tls-macros.h>
/* XXX Each architecture must have its own asm for now. */
#if !defined TLS_LE || !defined TLS_IE \
|| !defined TLS_LD || !defined TLS_GD
# error "No support for this architecture so far."
#endif
+26
View File
@@ -0,0 +1,26 @@
/* Bug 20419: test for stack overflow in elf/dl-load.c open_verify()
Copyright (C) 2018 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 creates a .so with 8MiB PT_NOTE segment.
On a typical Linux system with 8MiB "ulimit -s", that was enough
to trigger stack overflow in open_verify. */
.pushsection .note.big,"a"
.balign 4
.fill 8*1024*1024, 1, 0
.popsection
+26
View File
@@ -0,0 +1,26 @@
/* Bug 20419: test for stack overflow in elf/dl-load.c open_verify()
Copyright (C) 2018 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 file must be run from within a directory called "elf". */
int main (int argc, char *argv[])
{
/* Nothing to do here: merely linking against tst-big-note-lib.so triggers
the bug. */
return 0;
}
+15
View File
@@ -0,0 +1,15 @@
#include <stdio.h>
int
foo (void)
{
printf ("In %s:%s\n", __FILE__, __func__);
return 1;
}
int
foosub (void)
{
printf ("In %s:%s\n", __FILE__, __func__);
return 20;
}
+8
View File
@@ -0,0 +1,8 @@
#include <stdio.h>
int
bar (void)
{
printf ("In %s:%s\n", __FILE__, __func__);
return 123;
}
+8
View File
@@ -0,0 +1,8 @@
#include <stdio.h>
int
xyzzy (void)
{
printf ("In %s:%s\n", __FILE__, __func__);
return 21;
}
+144
View File
@@ -0,0 +1,144 @@
#include <dlfcn.h>
#include <stdio.h>
/* These numbers need to be coordinated with the offsets passed to make the combined .so. */
int offa = 64;
int offb = 128;
int offc = 192;
int
do_test (void)
{
void *p1 = __google_dlopen_with_offset ("$ORIGIN/tst-dlopen-offset-comb.so", offa * 1024, RTLD_LAZY);
if (!p1)
{
puts (dlerror ());
return 1;
}
int (*f) (void) = dlsym (p1, "foo");
if (f)
{
(*f)();
}
else
{
puts (dlerror ());
return 1;
}
void *p2 = __google_dlopen_with_offset ("$ORIGIN/tst-dlopen-offset-comb.so", offb * 1024, RTLD_LAZY);
int (*bar) (void) = dlsym (p2, "bar");
if (bar)
{
(*bar)();
}
else
{
puts (dlerror ());
return 1;
}
void *p3 = __google_dlopen_with_offset ("$ORIGIN/tst-dlopen-offset-comb.so", offc * 1024, RTLD_LAZY);
int (*xyzzy) (void) = dlsym (p3, "xyzzy");
if (xyzzy)
{
(*xyzzy)();
}
else
{
puts (dlerror ());
return 1;
}
if (p1)
dlclose (p1);
p1 = __google_dlopen_with_offset ("$ORIGIN/tst-dlopen-offset-comb.so", offa * 1024, RTLD_LAZY);
f = dlsym (p1, "someothersym");
if (!f)
{
puts (dlerror ());
puts (" (expected)");
}
else
{
puts ("Symbol found unexpectedly");
return 1;
}
f = dlsym (p1, "xyzzy");
if (!f)
{
puts (dlerror ());
puts (" (expected)");
}
else
{
puts ("Symbol found unexpectedly");
return 1;
}
p1 = __google_dlopen_with_offset ("$ORIGIN/tst-dlopen-offset-comb.so", offa * 1024, RTLD_LAZY);
f = dlsym (p1, "foo");
if (f)
{
(*f)();
}
else
{
puts (dlerror ());
return 1;
}
void *px = __google_dlopen_with_offset ("$ORIGIN/tst-dlopen-offset-comb.so", 0, RTLD_LAZY);
if (!px)
{
puts (dlerror ());
puts (" (expected)");
}
else
{
puts ("dlopen_with_offset succeeded unexpectedly");
return 1;
}
px = __google_dlopen_with_offset ("$ORIGIN/tst-dlopen-offset-mod1.so", 0, RTLD_LAZY);
f = dlsym (px, "foo");
if (f)
{
(*f)();
}
else
{
puts (dlerror ());
return 1;
}
px = __google_dlopen_with_offset ("$ORIGIN/nonexistent.so", 0, RTLD_LAZY);
if (!px)
{
puts (dlerror ());
puts (" (expected)");
}
else
{
puts ("dlopen_with_offset succeeded unexpectedly");
return 1;
}
return 0;
}
#define TIMEOUT 100
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
+46
View File
@@ -0,0 +1,46 @@
/* Test for DT_RELR in a shared library without DT_NEEDED.
Copyright (C) 2022 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <array_length.h>
static int o, x;
#define ELEMS O O O O O O O O X X X X X X X O O X O O X X X E X E E O X O E
#define E 0,
#define O &o,
#define X &x,
void *arr[] = { ELEMS };
#undef O
#undef X
#define O 1,
#define X 2,
static char val[] = { ELEMS };
int
foo (void)
{
int err = 0;
for (int i = 0; i < array_length (arr); i++)
if (!((arr[i] == 0 && val[i] == 0)
|| (arr[i] == &o && val[i] == 1)
|| (arr[i] == &x && val[i] == 2)))
err++;
return err;
}
+49
View File
@@ -0,0 +1,49 @@
/* Test for DT_RELR in a shared library without DT_VERNEED.
Copyright (C) 2022 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <array_length.h>
static int o, x;
#define ELEMS O O O O O O O O X X X X X X X O O X O O X X X E X E E O X O E
#define E 0,
#define O &o,
#define X &x,
void *arr[] = { ELEMS };
#undef O
#undef X
#define O 1,
#define X 2,
static char val[] = { ELEMS };
extern void bar (void);
int
foo (void)
{
int err = 0;
for (int i = 0; i < array_length (arr); i++)
if (!((arr[i] == 0 && val[i] == 0)
|| (arr[i] == &o && val[i] == 1)
|| (arr[i] == &x && val[i] == 2)))
err++;
bar ();
return err;
}
+22
View File
@@ -0,0 +1,22 @@
/* Test for DT_RELR in a shared library without DT_VERNEED.
Copyright (C) 2022 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
void
bar (void)
{
}
+19
View File
@@ -0,0 +1,19 @@
/* Test for DT_RELR in a shared library without libc.so on DT_NEEDED.
Copyright (C) 2022 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include "tst-relr-mod3a.c"
+19
View File
@@ -0,0 +1,19 @@
/* Test for DT_RELR in a shared library without libc.so on DT_NEEDED.
Copyright (C) 2022 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include "tst-relr-mod3b.c"
+3
View File
@@ -0,0 +1,3 @@
DT_RELR {
global: bar;
};
+1
View File
@@ -0,0 +1 @@
#include "tst-relr.c"
+65
View File
@@ -0,0 +1,65 @@
/* Basic tests for DT_RELR.
Copyright (C) 2022 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <link.h>
#include <stdbool.h>
#include <array_length.h>
#include <support/check.h>
static int o, x;
#define ELEMS O O O O O O O O X X X X X X X O O X O O X X X E X E E O X O E
#define E 0,
#define O &o,
#define X &x,
void *arr[] = { ELEMS };
#undef O
#undef X
#define O 1,
#define X 2,
static char val[] = { ELEMS };
static int
do_test (void)
{
ElfW(Dyn) *d = _DYNAMIC;
if (d)
{
bool has_relr = false;
for (; d->d_tag != DT_NULL; d++)
if (d->d_tag == DT_RELR)
has_relr = true;
#if defined __PIE__ || defined __pie__ || defined PIE || defined pie
TEST_VERIFY (has_relr);
#else
TEST_VERIFY (!has_relr);
#endif
}
for (int i = 0; i < array_length (arr); i++)
TEST_VERIFY ((arr[i] == 0 && val[i] == 0)
|| (arr[i] == &o && val[i] == 1)
|| (arr[i] == &x && val[i] == 2));
return 0;
}
#include <support/test-driver.c>
+27
View File
@@ -0,0 +1,27 @@
/* Test for DT_RELR in a shared library without DT_NEEDED.
Copyright (C) 2022 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
extern int foo (void);
static int
do_test (void)
{
return foo ();
}
#include <support/test-driver.c>
+27
View File
@@ -0,0 +1,27 @@
/* Test for DT_RELR in a shared library without libc.so on DT_NEEDED.
Copyright (C) 2022 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
extern int foo (void);
static int
do_test (void)
{
return foo ();
}
#include <support/test-driver.c>
+1
View File
@@ -0,0 +1 @@
#include "tst-relr3.c"
+25 -39
View File
@@ -1,13 +1,14 @@
/* glibc test for TLS in ld.so. */
#include <stdio.h>
#include "tls-macros.h"
/* Two common 'int' variables in TLS. */
COMMON_INT_DEF(foo);
COMMON_INT_DEF(bar);
__thread int foo, bar __attribute__ ((tls_model("local-exec")));
extern __thread int foo_gd asm ("foo") __attribute__ ((tls_model("global-dynamic")));
extern __thread int foo_ld asm ("foo") __attribute__ ((tls_model("local-dynamic")));
extern __thread int foo_ie asm ("foo") __attribute__ ((tls_model("initial-exec")));
extern __thread int bar_gd asm ("bar") __attribute__ ((tls_model("global-dynamic")));
extern __thread int bar_ld asm ("bar") __attribute__ ((tls_model("local-dynamic")));
extern __thread int bar_ie asm ("bar") __attribute__ ((tls_model("initial-exec")));
static int
do_test (void)
@@ -18,63 +19,48 @@ do_test (void)
/* Set the variable using the local exec model. */
puts ("set bar to 1 (LE)");
ap = TLS_LE (bar);
*ap = 1;
bar = 1;
/* Get variables using initial exec model. */
fputs ("get sum of foo and bar (IE)", stdout);
ap = TLS_IE (foo);
bp = TLS_IE (bar);
ap = &foo_ie;
bp = &bar_ie;
printf (" = %d\n", *ap + *bp);
result |= *ap + *bp != 1;
if (*ap != 0)
if (*ap != 0 || *bp != 1)
{
printf ("foo = %d\n", *ap);
result = 1;
}
if (*bp != 1)
{
printf ("bar = %d\n", *bp);
printf ("foo = %d\nbar = %d\n", *ap, *bp);
result = 1;
}
/* Get variables using local dynamic model. */
fputs ("get sum of foo and bar (LD)", stdout);
ap = TLS_LD (foo);
bp = TLS_LD (bar);
/* Get variables using local dynamic model or TLSDESC. */
fputs ("get sum of foo and bar (LD or TLSDESC)", stdout);
ap = &foo_ld;
bp = &bar_ld;
printf (" = %d\n", *ap + *bp);
result |= *ap + *bp != 1;
if (*ap != 0)
if (*ap != 0 || *bp != 1)
{
printf ("foo = %d\n", *ap);
result = 1;
}
if (*bp != 1)
{
printf ("bar = %d\n", *bp);
printf ("foo = %d\nbar = %d\n", *ap, *bp);
result = 1;
}
/* Get variables using generic dynamic model. */
fputs ("get sum of foo and bar (GD)", stdout);
ap = TLS_GD (foo);
bp = TLS_GD (bar);
/* Get variables using general dynamic model or TLSDESC. */
fputs ("get sum of foo and bar (GD or TLSDESC)", stdout);
ap = &foo_gd;
bp = &bar_gd;
printf (" = %d\n", *ap + *bp);
result |= *ap + *bp != 1;
if (*ap != 0)
if (*ap != 0 || *bp != 1)
{
printf ("foo = %d\n", *ap);
result = 1;
}
if (*bp != 1)
{
printf ("bar = %d\n", *bp);
printf ("foo = %d\nbar = %d\n", *ap, *bp);
result = 1;
}
return result;
}
-82
View File
@@ -1,82 +0,0 @@
/* glibc test for TLS in ld.so. */
#include <stdio.h>
#include "tls-macros.h"
/* Two 'int' variables in TLS. */
VAR_INT_DEF(foo);
VAR_INT_DEF(bar);
static int
do_test (void)
{
int result = 0;
int *ap, *bp;
/* Set the variable using the local exec model. */
puts ("set bar to 1 (LE)");
ap = TLS_LE (bar);
*ap = 1;
/* Get variables using initial exec model. */
fputs ("get sum of foo and bar (IE)", stdout);
ap = TLS_IE (foo);
bp = TLS_IE (bar);
printf (" = %d\n", *ap + *bp);
result |= *ap + *bp != 1;
if (*ap != 0)
{
printf ("foo = %d\n", *ap);
result = 1;
}
if (*bp != 1)
{
printf ("bar = %d\n", *bp);
result = 1;
}
/* Get variables using local dynamic model. */
fputs ("get sum of foo and bar (LD)", stdout);
ap = TLS_LD (foo);
bp = TLS_LD (bar);
printf (" = %d\n", *ap + *bp);
result |= *ap + *bp != 1;
if (*ap != 0)
{
printf ("foo = %d\n", *ap);
result = 1;
}
if (*bp != 1)
{
printf ("bar = %d\n", *bp);
result = 1;
}
/* Get variables using generic dynamic model. */
fputs ("get sum of foo and bar (GD)", stdout);
ap = TLS_GD (foo);
bp = TLS_GD (bar);
printf (" = %d\n", *ap + *bp);
result |= *ap + *bp != 1;
if (*ap != 0)
{
printf ("foo = %d\n", *ap);
result = 1;
}
if (*bp != 1)
{
printf ("bar = %d\n", *bp);
result = 1;
}
return result;
}
#include <support/test-driver.c>
+11 -15
View File
@@ -1,13 +1,12 @@
/* glibc test for TLS in ld.so. */
#include <stdio.h>
#include "tls-macros.h"
/* One define int variable, two externs. */
COMMON_INT_DECL(foo);
VAR_INT_DECL(bar);
VAR_INT_DEF(baz);
__thread int foo, bar __attribute__ ((tls_model("initial-exec")));
__thread int baz __attribute__ ((tls_model("local-exec")));
extern __thread int foo_gd __attribute__ ((alias("foo"), tls_model("global-dynamic")));
extern __thread int bar_gd __attribute__ ((alias("bar"), tls_model("global-dynamic")));
extern __thread int baz_ld __attribute__ ((alias("baz"), tls_model("local-dynamic")));
extern int in_dso (void);
@@ -22,23 +21,20 @@ do_test (void)
/* Set the variable using the local exec model. */
puts ("set baz to 3 (LE)");
ap = TLS_LE (baz);
*ap = 3;
baz = 3;
/* Get variables using initial exec model. */
puts ("set variables foo and bar (IE)");
ap = TLS_IE (foo);
*ap = 1;
bp = TLS_IE (bar);
*bp = 2;
foo = 1;
bar = 2;
/* Get variables using local dynamic model. */
fputs ("get sum of foo, bar (GD) and baz (LD)", stdout);
ap = TLS_GD (foo);
bp = TLS_GD (bar);
cp = TLS_LD (baz);
ap = &foo_gd;
bp = &bar_gd;
cp = &baz_ld;
printf (" = %d\n", *ap + *bp + *cp);
result |= *ap + *bp + *cp != 6;
if (*ap != 1)
+12 -12
View File
@@ -1,12 +1,12 @@
#include <stdio.h>
#include "tls-macros.h"
__thread int foo, bar __attribute__ ((tls_model("global-dynamic")));
extern __thread int baz __attribute__ ((tls_model("global-dynamic")));
extern __thread int foo_ie asm ("foo") __attribute__ ((tls_model("initial-exec")));
extern __thread int bar_ie asm ("bar") __attribute__ ((tls_model("initial-exec")));
extern __thread int baz_ie asm ("baz") __attribute__ ((tls_model("initial-exec")));
/* One define int variable, two externs. */
COMMON_INT_DEF(foo);
VAR_INT_DEF(bar);
VAR_INT_DECL(baz);
extern int in_dso (void);
@@ -19,8 +19,8 @@ in_dso (void)
/* Get variables using initial exec model. */
fputs ("get sum of foo and bar (IE)", stdout);
asm ("" ::: "memory");
ap = TLS_IE (foo);
bp = TLS_IE (bar);
ap = &foo_ie;
bp = &bar_ie;
printf (" = %d\n", *ap + *bp);
result |= *ap + *bp != 3;
if (*ap != 1)
@@ -35,11 +35,11 @@ in_dso (void)
}
/* Get variables using generic dynamic model. */
fputs ("get sum of foo and bar and baz (GD)", stdout);
ap = TLS_GD (foo);
bp = TLS_GD (bar);
cp = TLS_GD (baz);
/* Get variables using generic dynamic model or TLSDESC. */
fputs ("get sum of foo and bar and baz (GD or TLSDESC)", stdout);
ap = &foo;
bp = &bar;
cp = &baz;
printf (" = %d\n", *ap + *bp + *cp);
result |= *ap + *bp + *cp != 6;
if (*ap != 1)
+2 -4
View File
@@ -1,9 +1,7 @@
#include <stdio.h>
#include "tls-macros.h"
COMMON_INT_DEF(foo);
__thread int foo;
int
@@ -15,7 +13,7 @@ in_dso (int n, int *caller_foop)
puts ("foo"); /* Make sure PLT is used before macros. */
asm ("" ::: "memory");
foop = TLS_GD (foo);
foop = &foo;
if (caller_foop != NULL && foop != caller_foop)
{
+4 -4
View File
@@ -1,10 +1,10 @@
#include <stdio.h>
#include "tls-macros.h"
extern int in_dso (int n, int *caller_foop);
COMMON_INT_DEF(comm_n);
extern __thread int foo;
__thread int comm_n;
@@ -20,8 +20,8 @@ in_dso2 (void)
puts ("foo"); /* Make sure PLT is used before macros. */
asm ("" ::: "memory");
foop = TLS_GD (foo);
np = TLS_GD (comm_n);
foop = &foo;
np = &comm_n;
if (n != *np)
{
+2 -4
View File
@@ -1,9 +1,7 @@
#include <stdio.h>
#include "tls-macros.h"
COMMON_INT_DEF(baz);
__thread int baz;
int
@@ -15,7 +13,7 @@ in_dso (int n, int *caller_bazp)
puts ("foo"); /* Make sure PLT is used before macros. */
asm ("" ::: "memory");
bazp = TLS_GD (baz);
bazp = &baz;
if (caller_bazp != NULL && bazp != caller_bazp)
{
+1 -3
View File
@@ -1,3 +1 @@
#include "tls-macros.h"
COMMON_INT_DEF(foo);
__thread int foo;
+1 -3
View File
@@ -1,3 +1 @@
#include "tls-macros.h"
COMMON_INT_DEF(bar);
__thread int bar;
+2
View File
@@ -3,6 +3,8 @@
int
__attribute__((noinline))
/* Workaround for clang/lld failing to override this from a module. */
__attribute__((weak))
baz (int x)
{
abort ();
+41
View File
@@ -27,7 +27,48 @@ main (void)
}
mod1 ();
// Additional test to detect when the fastload hash table has bad pointers to
// names of unloaded libraries hanging around in it.
int (*mod1b) (void) = dlsym (h, "mod1b");
if (mod1b == NULL)
{
puts ("dlsym failed");
return 1;
}
mod1b ();
dlclose (h);
void *h2x = dlopen ("$ORIGIN/unload8mod2.so", RTLD_LAZY);
if (h2x == NULL)
{
puts ("dlopen unload8mod2.so failed");
return 1;
}
void *h2xx = dlopen ("$ORIGIN/unload8mod1x.so", RTLD_LAZY);
if (h2xx == NULL)
{
puts ("dlopen unload8mod1x.so failed");
return 1;
}
dlclose (h);
dlclose (h2x);
dlclose (h2xx);
void *h3xx = dlopen ("$ORIGIN/unload8mod3.so", RTLD_LAZY);
if (h3xx == NULL)
{
puts ("dlopen unload8mod3.so failed");
return 1;
}
dlclose (h3xx);
return 0;
}
+14
View File
@@ -1,3 +1,5 @@
#include <dlfcn.h>
extern void mod2 (void);
void
@@ -5,3 +7,15 @@ mod1 (void)
{
mod2 ();
}
int
mod1b (void)
{
void *h = dlopen ("$ORIGIN/unload8mod3.so", RTLD_LAZY);
if (h == NULL)
{
puts ("dlopen unload8mod3.so failed");
return 1;
}
return 0;
}
+32
View File
@@ -0,0 +1,32 @@
# Copyright (C) 2003-2013 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/>.
# Makefile for google-nsl-stub add-on subdirectory of GNU C Library.
# Based on libidn/Makefile.
subdir := google-nsl-stub
extra-libs = libnsl
extra-libs-others = $(extra-libs)
libnsl-routines := ypclnt
include $(..)Makeconfig
libnsl-inhibit-o = $(filter-out .os,$(object-suffixes))
include $(..)Rules
+6
View File
@@ -0,0 +1,6 @@
# This is a shell script fragment sourced by the main configure script.
# We're obliged to give here the canonical name that will be used to
# as a subdirectory to search for in other add-ons' sysdeps trees.
libc_add_on_canonical=google-nsl-stub
libc_add_on_subdirs=.
+1
View File
@@ -0,0 +1 @@
libnsl=1
+42
View File
@@ -0,0 +1,42 @@
/* Copyright (C) 2013 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 is a Google-local stub version of nis/ypclnt.c. These functions
are required for dynamic linking of some precompiled executables. */
#include <stdlib.h>
#include <stdio.h>
int yp_get_default_domain(char **domp) {
/* We duplicate glibc's error behavior and return a null pointer. */
*domp = NULL;
return 12; /* YPERR_NODOM */
}
static const char err[] = "not implemented in Google-local stub";
char *yperr_string(int incode) {
return err;
}
int yp_match(char *indomain, char *inmap, const char *inkey, int inkeylen,
char **outval, int *outvallen) {
*outval = malloc(2);
(*outval)[0] = '\n';
(*outval)[1] = '\0';
*outvallen = 0;
return 0;
}
+16 -2
View File
@@ -26,7 +26,7 @@ headers = iconv.h gconv.h
routines = iconv_open iconv iconv_close \
gconv_open gconv gconv_close gconv_db gconv_conf \
gconv_builtin gconv_simple gconv_trans gconv_cache
routines += gconv_dl
routines += gconv_dl gconv_charset
vpath %.c ../locale/programs ../intl
@@ -43,7 +43,8 @@ CFLAGS-charmap.c += -DCHARMAP_PATH='"$(i18ndir)/charmaps"' \
CFLAGS-linereader.c += -DNO_TRANSLITERATION
CFLAGS-simple-hash.c += -I../locale
tests = tst-iconv1 tst-iconv2 tst-iconv3 tst-iconv4 tst-iconv5 tst-iconv6
tests = tst-iconv1 tst-iconv2 tst-iconv3 tst-iconv4 tst-iconv5 tst-iconv6 \
tst-iconv8 # tst-iconv-opt needs work to add back
others = iconv_prog iconvconfig
install-others-programs = $(inst_bindir)/iconv
@@ -60,6 +61,7 @@ include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left))
ifeq ($(run-built-tests),yes)
xtests-special += $(objpfx)test-iconvconfig.out
tests-special += $(objpfx)tst-iconv_prog.out
endif
# Make a copy of the file because gconv module names are constructed
@@ -78,6 +80,13 @@ endif
include ../Rules
ifeq ($(run-built-tests),yes)
LOCALES := en_US.UTF-8
include ../gen-locales.mk
$(objpfx)tst-iconv-opt.out: $(gen-locales)
endif
$(inst_bindir)/iconv: $(objpfx)iconv_prog $(+force)
$(do-install-program)
@@ -92,3 +101,8 @@ $(objpfx)test-iconvconfig.out: /dev/null $(objpfx)iconvconfig
cmp $$tmp $(inst_gconvdir)/gconv-modules.cache; \
rm -f $$tmp) > $@; \
$(evaluate-test)
$(objpfx)tst-iconv_prog.out: tst-iconv_prog.sh $(objpfx)iconv_prog
$(BASH) $< $(common-objdir) '$(test-wrapper-env)' \
'$(run-program-env)' > $@; \
$(evaluate-test)
+3
View File
@@ -7,6 +7,9 @@ libc {
# functions shared with iconv program
__gconv_get_alias_db; __gconv_get_cache; __gconv_get_modules_db;
# functions used elsewhere in glibc
__gconv_open; __gconv_create_spec; __gconv_destroy_spec;
# function used by the gconv modules
__gconv_transliterate;
}
+228
View File
@@ -0,0 +1,228 @@
/* Charset name normalization.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <stdlib.h>
#include <ctype.h>
#include <locale.h>
#include <stdbool.h>
#include <string.h>
#include <sys/stat.h>
#include "gconv_int.h"
#include "gconv_charset.h"
/* This function returns a pointer to the last suffix in a conversion code
string. Valid suffixes matched by this function are of the form: '/' or ','
followed by arbitrary text that doesn't contain '/' or ','. It does not
edit the string in any way. The caller is expected to parse the suffix and
remove it (by e.g. truncating the string) before the next call. */
static char *
find_suffix (char *s)
{
/* The conversion code is in the form of a triplet, separated by '/' chars.
The third component of the triplet contains suffixes. If we don't have two
slashes, we don't have a suffix. */
int slash_count = 0;
char *suffix_term = NULL;
for (int i = 0; s[i] != '\0'; i++)
switch (s[i])
{
case '/':
slash_count++;
/* Fallthrough */
case ',':
suffix_term = &s[i];
}
if (slash_count >= 2)
return suffix_term;
return NULL;
}
struct gconv_parsed_code
{
char *code;
bool translit;
bool ignore;
};
/* This function parses an iconv_open encoding PC.CODE, strips any suffixes
(such as TRANSLIT or IGNORE) from it and sets corresponding flags in it. */
static void
gconv_parse_code (struct gconv_parsed_code *pc)
{
pc->translit = false;
pc->ignore = false;
while (1)
{
/* First drop any trailing whitespaces and separators. */
size_t len = strlen (pc->code);
while ((len > 0)
&& (isspace (pc->code[len - 1])
|| pc->code[len - 1] == ','
|| pc->code[len - 1] == '/'))
len--;
pc->code[len] = '\0';
if (len == 0)
return;
char * suffix = find_suffix (pc->code);
if (suffix == NULL)
{
/* At this point, we have processed and removed all suffixes from the
code and what remains of the code is suffix free. */
return;
}
else
{
/* A suffix is processed from the end of the code array going
backwards, one suffix at a time. The suffix is an index into the
code character array and points to: one past the end of the code
and any unprocessed suffixes, and to the beginning of the suffix
currently being processed during this iteration. We must process
this suffix and then drop it from the code by terminating the
preceding text with NULL.
We want to allow and recognize suffixes such as:
"/TRANSLIT" i.e. single suffix
"//TRANSLIT" i.e. single suffix and multiple separators
"//TRANSLIT/IGNORE" i.e. suffixes separated by "/"
"/TRANSLIT//IGNORE" i.e. suffixes separated by "//"
"//IGNORE,TRANSLIT" i.e. suffixes separated by ","
"//IGNORE," i.e. trailing ","
"//TRANSLIT/" i.e. trailing "/"
"//TRANSLIT//" i.e. trailing "//"
"/" i.e. empty suffix.
Unknown suffixes are silently discarded and ignored. */
if ((__strcasecmp_l (suffix,
GCONV_TRIPLE_SEPARATOR
GCONV_TRANSLIT_SUFFIX,
_nl_C_locobj_ptr) == 0)
|| (__strcasecmp_l (suffix,
GCONV_SUFFIX_SEPARATOR
GCONV_TRANSLIT_SUFFIX,
_nl_C_locobj_ptr) == 0))
pc->translit = true;
if ((__strcasecmp_l (suffix,
GCONV_TRIPLE_SEPARATOR
GCONV_IGNORE_ERRORS_SUFFIX,
_nl_C_locobj_ptr) == 0)
|| (__strcasecmp_l (suffix,
GCONV_SUFFIX_SEPARATOR
GCONV_IGNORE_ERRORS_SUFFIX,
_nl_C_locobj_ptr) == 0))
pc->ignore = true;
/* We just processed this suffix. We can now drop it from the
code string by truncating it at the suffix's position. */
suffix[0] = '\0';
}
}
}
/* This function accepts the charset names of the source and destination of the
conversion and populates *conv_spec with an equivalent conversion
specification that may later be used by __gconv_open. The charset names
might contain options in the form of suffixes that alter the conversion,
e.g. "ISO-10646/UTF-8/TRANSLIT". It processes the charset names, ignoring
and truncating any suffix options in fromcode, and processing and truncating
any suffix options in tocode. Supported suffix options ("TRANSLIT" or
"IGNORE") when found in tocode lead to the corresponding flag in *conv_spec
to be set to true. Unrecognized suffix options are silently discarded. If
the function succeeds, it returns conv_spec back to the caller. It returns
NULL upon failure. conv_spec must be allocated and freed by the caller. */
struct gconv_spec *
__gconv_create_spec (struct gconv_spec *conv_spec, const char *fromcode,
const char *tocode)
{
struct gconv_parsed_code pfc, ptc;
struct gconv_spec *ret = NULL;
pfc.code = __strdup (fromcode);
ptc.code = __strdup (tocode);
if ((pfc.code == NULL)
|| (ptc.code == NULL))
goto out;
gconv_parse_code (&pfc);
gconv_parse_code (&ptc);
/* We ignore suffixes in the fromcode because that is how the current
implementation has always handled them. Only suffixes in the tocode are
processed and handled. The reality is that invalid input in the input
character set should only be ignored if the fromcode specifies IGNORE.
The current implementation ignores invalid intput in the input character
set if the tocode contains IGNORE. We preserve this behavior for
backwards compatibility. In the future we may split the handling of
IGNORE to allow a finer grained specification of ignorning invalid input
and/or ignoring invalid output. */
conv_spec->translit = ptc.translit;
conv_spec->ignore = ptc.ignore;
/* 3 extra bytes because 1 extra for '\0', and 2 extra so strip might
be able to add one or two trailing '/' characters if necessary. */
conv_spec->fromcode = malloc (strlen (fromcode) + 3);
if (conv_spec->fromcode == NULL)
goto out;
conv_spec->tocode = malloc (strlen (tocode) + 3);
if (conv_spec->tocode == NULL)
{
free (conv_spec->fromcode);
conv_spec->fromcode = NULL;
goto out;
}
/* Strip unrecognized characters and ensure that the code has two '/'
characters as per conversion code triplet specification. */
strip (conv_spec->fromcode, pfc.code);
strip (conv_spec->tocode, ptc.code);
ret = conv_spec;
out:
free (pfc.code);
free (ptc.code);
return ret;
}
libc_hidden_def (__gconv_create_spec)
void
__gconv_destroy_spec (struct gconv_spec *conv_spec)
{
free (conv_spec->fromcode);
free (conv_spec->tocode);
return;
}
libc_hidden_def (__gconv_destroy_spec)
+33 -1
View File
@@ -19,9 +19,41 @@
#include <ctype.h>
#include <locale.h>
#include <stdbool.h>
#include <string.h>
#include <sys/stat.h>
#include <stdlib.h>
#include "gconv_int.h"
static void
/* An iconv encoding is in the form of a triplet, with parts separated by
a '/' character. The first part is the standard name, the second part is
the character set, and the third part is the error handler. If the first
part is sufficient to identify both the standard and the character set
then the second part can be empty e.g. UTF-8//. If the first part is not
sufficient to identify both the standard and the character set then the
second part is required e.g. ISO-10646/UTF8/. If neither the first or
second parts are provided e.g. //, then the current locale is used.
The actual values used in the first and second parts are not entirely
relevant to the implementation. The values themselves are used in a hash
table to lookup modules and so the naming convention of the first two parts
is somewhat arbitrary and only helps locate the entries in the cache.
The third part is the error handler and is comprised of a ',' or '/'
separated list of suffixes. Currently, we support "TRANSLIT" for
transliteration and "IGNORE" for ignoring conversion errors due to
unrecognized input characters. */
#define GCONV_TRIPLE_SEPARATOR "/"
#define GCONV_SUFFIX_SEPARATOR ","
#define GCONV_TRANSLIT_SUFFIX "TRANSLIT"
#define GCONV_IGNORE_ERRORS_SUFFIX "IGNORE"
/* This function copies in-order, characters from the source 's' that are
either alpha-numeric or one in one of these: "_-.,:/" - into the destination
'wp' while dropping all other characters. In the process, it converts all
alphabetical characters to upper case. It then appends up to two '/'
characters so that the total number of '/'es in the destination is 2. */
static inline void __attribute__ ((unused, always_inline))
strip (char *wp, const char *s)
{
int slash_count = 0;
+36 -4
View File
@@ -92,6 +92,15 @@ struct gconv_module
};
/* The specification of the conversion that needs to be performed. */
struct gconv_spec
{
char *fromcode;
char *tocode;
bool translit;
bool ignore;
};
/* Flags for `gconv_open'. */
enum
{
@@ -154,10 +163,33 @@ __libc_lock_define (extern, __gconv_lock attribute_hidden)
})
/* Return in *HANDLE decriptor for transformation from FROMSET to TOSET. */
extern int __gconv_open (const char *toset, const char *fromset,
__gconv_t *handle, int flags)
attribute_hidden;
/* Return in *HANDLE, a decriptor for the transformation. The function expects
the specification of the transformation in the structure pointed to by
CONV_SPEC. It only reads *CONV_SPEC and does not take ownership of it. */
extern int __gconv_open (struct gconv_spec *conv_spec,
__gconv_t *handle, int flags);
libc_hidden_proto (__gconv_open)
/* This function accepts the charset names of the source and destination of the
conversion and populates *conv_spec with an equivalent conversion
specification that may later be used by __gconv_open. The charset names
might contain options in the form of suffixes that alter the conversion,
e.g. "ISO-10646/UTF-8/TRANSLIT". It processes the charset names, ignoring
and truncating any suffix options in fromcode, and processing and truncating
any suffix options in tocode. Supported suffix options ("TRANSLIT" or
"IGNORE") when found in tocode lead to the corresponding flag in *conv_spec
to be set to true. Unrecognized suffix options are silently discarded. If
the function succeeds, it returns conv_spec back to the caller. It returns
NULL upon failure. */
extern struct gconv_spec *
__gconv_create_spec (struct gconv_spec *conv_spec, const char *fromcode,
const char *tocode);
libc_hidden_proto (__gconv_create_spec)
/* This function frees all heap memory allocated by __gconv_create_spec. */
extern void
__gconv_destroy_spec (struct gconv_spec *conv_spec);
libc_hidden_proto (__gconv_destroy_spec)
/* Free resources associated with transformation descriptor CD. */
extern int __gconv_close (__gconv_t cd)
+13 -51
View File
@@ -27,7 +27,7 @@
int
__gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
__gconv_open (struct gconv_spec *conv_spec, __gconv_t *handle,
int flags)
{
struct __gconv_step *steps;
@@ -36,77 +36,38 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
size_t cnt = 0;
int res;
int conv_flags = 0;
const char *errhand;
const char *ignore;
bool translit = false;
char *tocode, *fromcode;
/* Find out whether any error handling method is specified. */
errhand = strchr (toset, '/');
if (errhand != NULL)
errhand = strchr (errhand + 1, '/');
if (__glibc_likely (errhand != NULL))
{
if (*++errhand == '\0')
errhand = NULL;
else
{
/* Make copy without the error handling description. */
char *newtoset = (char *) alloca (errhand - toset + 1);
char *tok;
char *ptr = NULL /* Work around a bogus warning */;
translit = conv_spec->translit;
newtoset[errhand - toset] = '\0';
toset = memcpy (newtoset, toset, errhand - toset);
if (conv_spec->ignore)
conv_flags |= __GCONV_IGNORE_ERRORS;
/* Find the appropriate transliteration handlers. */
tok = strdupa (errhand);
tok = __strtok_r (tok, ",", &ptr);
while (tok != NULL)
{
if (__strcasecmp_l (tok, "TRANSLIT", _nl_C_locobj_ptr) == 0)
translit = true;
else if (__strcasecmp_l (tok, "IGNORE", _nl_C_locobj_ptr) == 0)
/* Set the flag to ignore all errors. */
conv_flags |= __GCONV_IGNORE_ERRORS;
tok = __strtok_r (NULL, ",", &ptr);
}
}
}
/* For the source character set we ignore the error handler specification.
XXX Is this really always the best? */
ignore = strchr (fromset, '/');
if (ignore != NULL && (ignore = strchr (ignore + 1, '/')) != NULL
&& *++ignore != '\0')
{
char *newfromset = (char *) alloca (ignore - fromset + 1);
newfromset[ignore - fromset] = '\0';
fromset = memcpy (newfromset, fromset, ignore - fromset);
}
tocode = conv_spec->tocode;
fromcode = conv_spec->fromcode;
/* If the string is empty define this to mean the charset of the
currently selected locale. */
if (strcmp (toset, "//") == 0)
if (strcmp (tocode, "//") == 0)
{
const char *codeset = _NL_CURRENT (LC_CTYPE, CODESET);
size_t len = strlen (codeset);
char *dest;
toset = dest = (char *) alloca (len + 3);
tocode = dest = (char *) alloca (len + 3);
memcpy (__mempcpy (dest, codeset, len), "//", 3);
}
if (strcmp (fromset, "//") == 0)
if (strcmp (fromcode, "//") == 0)
{
const char *codeset = _NL_CURRENT (LC_CTYPE, CODESET);
size_t len = strlen (codeset);
char *dest;
fromset = dest = (char *) alloca (len + 3);
fromcode = dest = (char *) alloca (len + 3);
memcpy (__mempcpy (dest, codeset, len), "//", 3);
}
res = __gconv_find_transform (toset, fromset, &steps, &nsteps, flags);
res = __gconv_find_transform (tocode, fromcode, &steps, &nsteps, flags);
if (res == __GCONV_OK)
{
/* Allocate room for handle. */
@@ -205,3 +166,4 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
*handle = result;
return res;
}
libc_hidden_def (__gconv_open)
+4 -12
View File
@@ -237,11 +237,9 @@ ucs4_internal_loop (struct __gconv_step *step,
int flags = step_data->__flags;
const unsigned char *inptr = *inptrp;
unsigned char *outptr = *outptrp;
size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
int result;
size_t cnt;
for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
for (; inptr + 4 <= inend && outptr + 4 <= outend; inptr += 4)
{
uint32_t inval;
@@ -304,11 +302,9 @@ ucs4_internal_loop_unaligned (struct __gconv_step *step,
int flags = step_data->__flags;
const unsigned char *inptr = *inptrp;
unsigned char *outptr = *outptrp;
size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
int result;
size_t cnt;
for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
for (; inptr + 4 <= inend && outptr + 4 <= outend; inptr += 4)
{
if (__glibc_unlikely (inptr[0] > 0x80))
{
@@ -607,11 +603,9 @@ ucs4le_internal_loop (struct __gconv_step *step,
int flags = step_data->__flags;
const unsigned char *inptr = *inptrp;
unsigned char *outptr = *outptrp;
size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
int result;
size_t cnt;
for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
for (; inptr + 4 <= inend && outptr + 4 <= outend; inptr += 4)
{
uint32_t inval;
@@ -677,11 +671,9 @@ ucs4le_internal_loop_unaligned (struct __gconv_step *step,
int flags = step_data->__flags;
const unsigned char *inptr = *inptrp;
unsigned char *outptr = *outptrp;
size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
int result;
size_t cnt;
for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
for (; inptr + 4 <= inend && outptr + 4 <= outend; inptr += 4)
{
if (__glibc_unlikely (inptr[3] > 0x80))
{
+7 -41
View File
@@ -31,49 +31,15 @@
iconv_t
iconv_open (const char *tocode, const char *fromcode)
{
/* Normalize the name. We remove all characters beside alpha-numeric,
'_', '-', '/', '.', and ':'. */
size_t tocode_len = strlen (tocode) + 3;
char *tocode_conv;
bool tocode_usealloca = __libc_use_alloca (tocode_len);
if (tocode_usealloca)
tocode_conv = (char *) alloca (tocode_len);
else
{
tocode_conv = (char *) malloc (tocode_len);
if (tocode_conv == NULL)
return (iconv_t) -1;
}
strip (tocode_conv, tocode);
tocode = (tocode_conv[2] == '\0' && tocode[0] != '\0'
? upstr (tocode_conv, tocode) : tocode_conv);
size_t fromcode_len = strlen (fromcode) + 3;
char *fromcode_conv;
bool fromcode_usealloca = __libc_use_alloca (fromcode_len);
if (fromcode_usealloca)
fromcode_conv = (char *) alloca (fromcode_len);
else
{
fromcode_conv = (char *) malloc (fromcode_len);
if (fromcode_conv == NULL)
{
if (! tocode_usealloca)
free (tocode_conv);
return (iconv_t) -1;
}
}
strip (fromcode_conv, fromcode);
fromcode = (fromcode_conv[2] == '\0' && fromcode[0] != '\0'
? upstr (fromcode_conv, fromcode) : fromcode_conv);
__gconv_t cd;
int res = __gconv_open (tocode, fromcode, &cd, 0);
struct gconv_spec conv_spec;
if (! fromcode_usealloca)
free (fromcode_conv);
if (! tocode_usealloca)
free (tocode_conv);
if (__gconv_create_spec (&conv_spec, fromcode, tocode) == NULL)
return (iconv_t) -1;
int res = __gconv_open (&conv_spec, &cd, 0);
__gconv_destroy_spec (&conv_spec);
if (__builtin_expect (res, __GCONV_OK) != __GCONV_OK)
{
+23 -40
View File
@@ -39,6 +39,7 @@
#include <gconv_int.h>
#include "iconv_prog.h"
#include "iconvconfig.h"
#include "gconv_charset.h"
/* Get libc version number. */
#include "../version.h"
@@ -118,8 +119,7 @@ main (int argc, char *argv[])
{
int status = EXIT_SUCCESS;
int remaining;
iconv_t cd;
const char *orig_to_code;
__gconv_t cd;
struct charmap_t *from_charmap = NULL;
struct charmap_t *to_charmap = NULL;
@@ -139,39 +139,6 @@ main (int argc, char *argv[])
exit (EXIT_SUCCESS);
}
/* If we have to ignore errors make sure we use the appropriate name for
the to-character-set. */
orig_to_code = to_code;
if (omit_invalid)
{
const char *errhand = strchrnul (to_code, '/');
int nslash = 2;
char *newp;
char *cp;
if (*errhand == '/')
{
--nslash;
errhand = strchrnul (errhand + 1, '/');
if (*errhand == '/')
{
--nslash;
errhand = strchr (errhand, '\0');
}
}
newp = (char *) alloca (errhand - to_code + nslash + 7 + 1);
cp = mempcpy (newp, to_code, errhand - to_code);
while (nslash-- > 0)
*cp++ = '/';
if (cp[-1] != '/')
*cp++ = ',';
memcpy (cp, "IGNORE", sizeof ("IGNORE"));
to_code = newp;
}
/* POSIX 1003.2b introduces a silly thing: the arguments to -t anf -f
can be file names of charmaps. In this case iconv will have to read
those charmaps and use them to do the conversion. But there are
@@ -184,10 +151,10 @@ main (int argc, char *argv[])
file. */
from_charmap = charmap_read (from_code, /*0, 1*/1, 0, 0, 0);
if (strchr (orig_to_code, '/') != NULL)
if (strchr (to_code, '/') != NULL)
/* The to-name might be a charmap file name. Try reading the
file. */
to_charmap = charmap_read (orig_to_code, /*0, 1,*/1, 0, 0, 0);
to_charmap = charmap_read (to_code, /*0, 1,*/1, 0, 0, 0);
/* At this point we have to handle two cases. The first one is
@@ -201,9 +168,25 @@ main (int argc, char *argv[])
argc, remaining, argv, output_file);
else
{
struct gconv_spec conv_spec;
int res;
if (__gconv_create_spec (&conv_spec, from_code, to_code) == NULL)
{
error (EXIT_FAILURE, errno,
_("failed to start conversion processing"));
exit (1);
}
if (omit_invalid)
conv_spec.ignore = true;
/* Let's see whether we have these coded character sets. */
cd = iconv_open (to_code, from_code);
if (cd == (iconv_t) -1)
res = __gconv_open (&conv_spec, &cd, 0);
__gconv_destroy_spec (&conv_spec);
if (res != __GCONV_OK)
{
if (errno == EINVAL)
{
@@ -221,7 +204,7 @@ main (int argc, char *argv[])
const char *from_pretty =
(from_code[0] ? from_code : nl_langinfo (CODESET));
const char *to_pretty =
(orig_to_code[0] ? orig_to_code : nl_langinfo (CODESET));
(to_code[0] ? to_code : nl_langinfo (CODESET));
if (from_wrong)
{
+347
View File
@@ -0,0 +1,347 @@
/* Test iconv's TRANSLIT and IGNORE option handling
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <iconv.h>
#include <locale.h>
#include <errno.h>
#include <string.h>
#include <support/support.h>
#include <support/check.h>
/* Run one iconv test. Arguments:
to: destination character set and options
from: source character set
input: input string to be converted
exp_in: expected number of bytes consumed
exp_ret: expected return value (error or number of irreversible conversions)
exp_out: expected output string
exp_err: expected value of `errno' after iconv returns. */
static void
test_iconv (const char *to, const char *from, char *input, size_t exp_in,
size_t exp_ret, const char *exp_out, int exp_err)
{
iconv_t cd;
char outbuf[500];
size_t inlen, outlen;
char *inptr, *outptr;
size_t n;
cd = iconv_open (to, from);
TEST_VERIFY (cd != (iconv_t) -1);
inlen = strlen (input);
outlen = sizeof (outbuf);
inptr = input;
outptr = outbuf;
errno = 0;
n = iconv (cd, &inptr, &inlen, &outptr, &outlen);
TEST_COMPARE (n, exp_ret);
TEST_VERIFY (inptr == input + exp_in);
TEST_COMPARE (errno, exp_err);
TEST_COMPARE_BLOB (outbuf, outptr - outbuf, exp_out, strlen (exp_out));
TEST_VERIFY (iconv_close (cd) == 0);
}
/* We test option parsing by converting UTF-8 inputs to ASCII under various
option combinations. The UTF-8 inputs fall into three categories:
- ASCII-only,
- non-ASCII,
- non-ASCII with invalid UTF-8 characters. */
/* 1. */
char ascii[] = "Just some ASCII text";
/* 2. Valid UTF-8 input and some corresponding expected outputs with various
options. The two non-ASCII characters below are accented alphabets:
an `a' then an `o'. */
char utf8[] = "UTF-8 text with \u00E1 couple \u00F3f non-ASCII characters";
char u2a[] = "UTF-8 text with ";
char u2a_translit[] = "UTF-8 text with a couple of non-ASCII characters";
char u2a_ignore[] = "UTF-8 text with couple f non-ASCII characters";
/* 3. Invalid UTF-8 input and some corresponding expected outputs. \xff is
invalid UTF-8. It's followed by some valid but non-ASCII UTF-8. */
char iutf8[] = "Invalid UTF-8 \xff\u27E6text\u27E7";
char iu2a[] = "Invalid UTF-8 ";
char iu2a_ignore[] = "Invalid UTF-8 text";
char iu2a_both[] = "Invalid UTF-8 [|text|]";
/* 4. Another invalid UTF-8 input and corresponding expected outputs. This time
the valid non-ASCII UTF-8 characters appear before the invalid \xff. */
char jutf8[] = "Invalid \u27E6UTF-8\u27E7 \xfftext";
char ju2a[] = "Invalid ";
char ju2a_translit[] = "Invalid [|UTF-8|] ";
char ju2a_ignore[] = "Invalid UTF-8 text";
char ju2a_both[] = "Invalid [|UTF-8|] text";
/* We also test option handling for character set names that have the form
"A/B". In this test, we test conversions "ISO-10646/UTF-8", and either
ISO-8859-1 or ASCII. */
/* 5. Accented 'A' and 'a' characters in ISO-8859-1 and UTF-8, and an
equivalent ASCII transliteration. */
char iso8859_1_a[] = {0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, /* Accented A's. */
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, /* Accented a's. */
0x00};
char utf8_a[] = "\u00C0\u00C1\u00C2\u00C3\u00C4\u00C5"
"\u00E0\u00E1\u00E2\u00E3\u00E4\u00E5";
char ascii_a[] = "AAAAAAaaaaaa";
/* 6. An invalid ASCII string where [0] is invalid and [1] is '~'. */
char iascii [] = {0x80, '~', '\0'};
char empty[] = "";
char ia2u_ignore[] = "~";
static int
do_test (void)
{
xsetlocale (LC_ALL, "en_US.UTF-8");
/* 0. iconv_open should gracefully fail for invalid character sets. */
TEST_VERIFY (iconv_open ("INVALID", "UTF-8") == (iconv_t) -1);
TEST_VERIFY (iconv_open ("UTF-8", "INVALID") == (iconv_t) -1);
TEST_VERIFY (iconv_open ("INVALID", "INVALID") == (iconv_t) -1);
/* 1. ASCII-only UTF-8 input should convert to ASCII with no changes: */
test_iconv ("ASCII", "UTF-8", ascii, strlen (ascii), 0, ascii, 0);
test_iconv ("ASCII//", "UTF-8", ascii, strlen (ascii), 0, ascii, 0);
test_iconv ("ASCII//TRANSLIT", "UTF-8", ascii, strlen (ascii), 0, ascii, 0);
test_iconv ("ASCII//TRANSLIT//", "UTF-8", ascii, strlen (ascii), 0, ascii,
0);
test_iconv ("ASCII//IGNORE", "UTF-8", ascii, strlen (ascii), 0, ascii, 0);
test_iconv ("ASCII//IGNORE//", "UTF-8", ascii, strlen (ascii), 0, ascii, 0);
/* 2. Valid UTF-8 input with non-ASCII characters: */
/* EILSEQ when converted to ASCII. */
test_iconv ("ASCII", "UTF-8", utf8, strlen (u2a), (size_t) -1, u2a, EILSEQ);
/* Converted without error with TRANSLIT enabled. */
test_iconv ("ASCII//TRANSLIT", "UTF-8", utf8, strlen (utf8), 2, u2a_translit,
0);
/* EILSEQ with IGNORE enabled. Non-ASCII chars dropped from output. */
test_iconv ("ASCII//IGNORE", "UTF-8", utf8, strlen (utf8), (size_t) -1,
u2a_ignore, EILSEQ);
/* With TRANSLIT and IGNORE enabled, transliterated without error. We test
four combinations. */
test_iconv ("ASCII//TRANSLIT,IGNORE", "UTF-8", utf8, strlen (utf8), 2,
u2a_translit, 0);
test_iconv ("ASCII//TRANSLIT//IGNORE", "UTF-8", utf8, strlen (utf8), 2,
u2a_translit, 0);
test_iconv ("ASCII//IGNORE,TRANSLIT", "UTF-8", utf8, strlen (utf8), 2,
u2a_translit, 0);
/* Due to bug 19519, iconv was ignoring TRANSLIT for the following input. */
test_iconv ("ASCII//IGNORE//TRANSLIT", "UTF-8", utf8, strlen (utf8), 2,
u2a_translit, 0);
/* Misspellings of TRANSLIT and IGNORE are ignored, but conversion still
works while respecting any other correctly spelled options. */
test_iconv ("ASCII//T", "UTF-8", utf8, strlen (u2a), (size_t) -1, u2a,
EILSEQ);
test_iconv ("ASCII//TRANSLITERATE", "UTF-8", utf8, strlen (u2a), (size_t) -1,
u2a, EILSEQ);
test_iconv ("ASCII//I", "UTF-8", utf8, strlen (u2a), (size_t) -1, u2a,
EILSEQ);
test_iconv ("ASCII//IGNORED", "UTF-8", utf8, strlen (u2a), (size_t) -1, u2a,
EILSEQ);
test_iconv ("ASCII//TRANSLITERATE//IGNORED", "UTF-8", utf8, strlen (u2a),
(size_t) -1, u2a, EILSEQ);
test_iconv ("ASCII//IGNORED,TRANSLITERATE", "UTF-8", utf8, strlen (u2a),
(size_t) -1, u2a, EILSEQ);
test_iconv ("ASCII//T//I", "UTF-8", utf8, strlen (u2a), (size_t) -1, u2a,
EILSEQ);
test_iconv ("ASCII//TRANSLIT//I", "UTF-8", utf8, strlen (utf8), 2,
u2a_translit, 0);
/* Due to bug 19519, iconv was ignoring TRANSLIT for the following input. */
test_iconv ("ASCII//I//TRANSLIT", "UTF-8", utf8, strlen (utf8), 2,
u2a_translit, 0);
test_iconv ("ASCII//IGNORED,TRANSLIT", "UTF-8", utf8, strlen (utf8), 2,
u2a_translit, 0);
test_iconv ("ASCII//TRANSLIT,IGNORED", "UTF-8", utf8, strlen (utf8), 2,
u2a_translit, 0);
test_iconv ("ASCII//IGNORE,T", "UTF-8", utf8, strlen (utf8), (size_t) -1,
u2a_ignore, EILSEQ);
test_iconv ("ASCII//T,IGNORE", "UTF-8", utf8, strlen (utf8), (size_t) -1,
u2a_ignore, EILSEQ);
/* Due to bug 19519, iconv was ignoring IGNORE for the following input. */
test_iconv ("ASCII//TRANSLITERATE//IGNORE", "UTF-8", utf8, strlen (utf8),
(size_t) -1, u2a_ignore, EILSEQ);
test_iconv ("ASCII//IGNORE//TRANSLITERATE", "UTF-8", utf8, strlen (utf8),
(size_t) -1, u2a_ignore, EILSEQ);
/* 3. Invalid UTF-8 followed by some valid non-ASCII UTF-8 characters: */
/* EILSEQ; output is truncated at the first invalid UTF-8 character. */
test_iconv ("ASCII", "UTF-8", iutf8, strlen (iu2a), (size_t) -1, iu2a,
EILSEQ);
/* With TRANSLIT enabled: EILSEQ; output still truncated at the first invalid
UTF-8 character. */
test_iconv ("ASCII//TRANSLIT", "UTF-8", iutf8, strlen (iu2a), (size_t) -1,
iu2a, EILSEQ);
/* With IGNORE enabled: EILSEQ; output omits invalid UTF-8 characters and
valid UTF-8 non-ASCII characters. */
test_iconv ("ASCII//IGNORE", "UTF-8", iutf8, strlen (iutf8), (size_t) -1,
iu2a_ignore, EILSEQ);
/* With TRANSLIT and IGNORE enabled, output omits only invalid UTF-8
characters and transliterates valid non-ASCII UTF-8 characters. We test
four combinations. */
test_iconv ("ASCII//TRANSLIT,IGNORE", "UTF-8", iutf8, strlen (iutf8), 2,
iu2a_both, 0);
/* Due to bug 19519, iconv was ignoring IGNORE for the following input. */
test_iconv ("ASCII//TRANSLIT//IGNORE", "UTF-8", iutf8, strlen (iutf8), 2,
iu2a_both, 0);
test_iconv ("ASCII//IGNORE,TRANSLIT", "UTF-8", iutf8, strlen (iutf8), 2,
iu2a_both, 0);
/* Due to bug 19519, iconv was ignoring TRANSLIT for the following input. */
test_iconv ("ASCII//IGNORE//TRANSLIT", "UTF-8", iutf8, strlen (iutf8), 2,
iu2a_both, 0);
/* 4. Invalid UTF-8 with valid non-ASCII UTF-8 chars appearing first: */
/* EILSEQ; output is truncated at the first non-ASCII character. */
test_iconv ("ASCII", "UTF-8", jutf8, strlen (ju2a), (size_t) -1, ju2a,
EILSEQ);
/* With TRANSLIT enabled: EILSEQ; output now truncated at the first invalid
UTF-8 character. */
test_iconv ("ASCII//TRANSLIT", "UTF-8", jutf8, strlen (jutf8) - 5,
(size_t) -1, ju2a_translit, EILSEQ);
test_iconv ("ASCII//translit", "UTF-8", jutf8, strlen (jutf8) - 5,
(size_t) -1, ju2a_translit, EILSEQ);
/* With IGNORE enabled: EILSEQ; output omits invalid UTF-8 characters and
valid UTF-8 non-ASCII characters. */
test_iconv ("ASCII//IGNORE", "UTF-8", jutf8, strlen (jutf8), (size_t) -1,
ju2a_ignore, EILSEQ);
test_iconv ("ASCII//ignore", "UTF-8", jutf8, strlen (jutf8), (size_t) -1,
ju2a_ignore, EILSEQ);
/* With TRANSLIT and IGNORE enabled, output omits only invalid UTF-8
characters and transliterates valid non-ASCII UTF-8 characters. We test
several combinations. */
test_iconv ("ASCII//TRANSLIT,IGNORE", "UTF-8", jutf8, strlen (jutf8), 2,
ju2a_both, 0);
/* Due to bug 19519, iconv was ignoring IGNORE for the following input. */
test_iconv ("ASCII//TRANSLIT//IGNORE", "UTF-8", jutf8, strlen (jutf8), 2,
ju2a_both, 0);
test_iconv ("ASCII//IGNORE,TRANSLIT", "UTF-8", jutf8, strlen (jutf8), 2,
ju2a_both, 0);
/* Due to bug 19519, iconv was ignoring TRANSLIT for the following input. */
test_iconv ("ASCII//IGNORE//TRANSLIT", "UTF-8", jutf8, strlen (jutf8), 2,
ju2a_both, 0);
test_iconv ("ASCII//translit,ignore", "UTF-8", jutf8, strlen (jutf8), 2,
ju2a_both, 0);
/* Trailing whitespace and separators should be ignored. */
test_iconv ("ASCII//IGNORE,TRANSLIT ", "UTF-8", jutf8, strlen (jutf8), 2,
ju2a_both, 0);
test_iconv ("ASCII//IGNORE,TRANSLIT/", "UTF-8", jutf8, strlen (jutf8), 2,
ju2a_both, 0);
test_iconv ("ASCII//IGNORE,TRANSLIT//", "UTF-8", jutf8, strlen (jutf8), 2,
ju2a_both, 0);
test_iconv ("ASCII//IGNORE,TRANSLIT,", "UTF-8", jutf8, strlen (jutf8), 2,
ju2a_both, 0);
test_iconv ("ASCII//IGNORE,TRANSLIT,,", "UTF-8", jutf8, strlen (jutf8), 2,
ju2a_both, 0);
test_iconv ("ASCII//IGNORE,TRANSLIT /,", "UTF-8", jutf8, strlen (jutf8), 2,
ju2a_both, 0);
/* TRANSLIT or IGNORE suffixes in fromcode should be ignored. */
test_iconv ("ASCII", "UTF-8//TRANSLIT", jutf8, strlen (ju2a), (size_t) -1,
ju2a, EILSEQ);
test_iconv ("ASCII", "UTF-8//IGNORE", jutf8, strlen (ju2a), (size_t) -1,
ju2a, EILSEQ);
test_iconv ("ASCII", "UTF-8//TRANSLIT,IGNORE", jutf8, strlen (ju2a),
(size_t) -1, ju2a, EILSEQ);
/* 5. Charset names of the form "A/B/": */
/* ISO-8859-1 is converted to UTF-8 without needing transliteration. */
test_iconv ("ISO-10646/UTF-8", "ISO-8859-1", iso8859_1_a,
strlen (iso8859_1_a), 0, utf8_a, 0);
test_iconv ("ISO-10646/UTF-8/", "ISO-8859-1", iso8859_1_a,
strlen (iso8859_1_a), 0, utf8_a, 0);
test_iconv ("ISO-10646/UTF-8/IGNORE", "ISO-8859-1", iso8859_1_a,
strlen (iso8859_1_a), 0, utf8_a, 0);
test_iconv ("ISO-10646/UTF-8//IGNORE", "ISO-8859-1", iso8859_1_a,
strlen (iso8859_1_a), 0, utf8_a, 0);
test_iconv ("ISO-10646/UTF-8/TRANSLIT", "ISO-8859-1", iso8859_1_a,
strlen (iso8859_1_a), 0, utf8_a, 0);
test_iconv ("ISO-10646/UTF-8//TRANSLIT", "ISO-8859-1", iso8859_1_a,
strlen (iso8859_1_a), 0, utf8_a, 0);
test_iconv ("ISO-10646/UTF-8//TRANSLIT/IGNORE", "ISO-8859-1", iso8859_1_a,
strlen (iso8859_1_a), 0, utf8_a, 0);
test_iconv ("ISO-10646/UTF-8//TRANSLIT//IGNORE", "ISO-8859-1", iso8859_1_a,
strlen (iso8859_1_a), 0, utf8_a, 0);
test_iconv ("ISO-10646/UTF-8/TRANSLIT,IGNORE", "ISO-8859-1", iso8859_1_a,
strlen (iso8859_1_a), 0, utf8_a, 0);
/* UTF-8 with accented A's is converted to ASCII with transliteration. */
test_iconv ("ASCII", "ISO-10646/UTF-8", utf8_a,
0, (size_t) -1, empty, EILSEQ);
test_iconv ("ASCII//IGNORE", "ISO-10646/UTF-8", utf8_a,
strlen (utf8_a), (size_t) -1, empty, EILSEQ);
test_iconv ("ASCII//TRANSLIT", "ISO-10646/UTF-8", utf8_a,
strlen (utf8_a), 12, ascii_a, 0);
/* Invalid ASCII is converted to UTF-8 only with IGNORE. */
test_iconv ("ISO-10646/UTF-8", "ASCII", iascii, strlen (empty), (size_t) -1,
empty, EILSEQ);
test_iconv ("ISO-10646/UTF-8/TRANSLIT", "ASCII", iascii, strlen (empty),
(size_t) -1, empty, EILSEQ);
test_iconv ("ISO-10646/UTF-8/IGNORE", "ASCII", iascii, strlen (iascii),
(size_t) -1, ia2u_ignore, EILSEQ);
test_iconv ("ISO-10646/UTF-8/TRANSLIT,IGNORE", "ASCII", iascii,
strlen (iascii), (size_t) -1, ia2u_ignore, EILSEQ);
/* Due to bug 19519, iconv was ignoring IGNORE for the following three
inputs: */
test_iconv ("ISO-10646/UTF-8/TRANSLIT/IGNORE", "ASCII", iascii,
strlen (iascii), (size_t) -1, ia2u_ignore, EILSEQ);
test_iconv ("ISO-10646/UTF-8//TRANSLIT,IGNORE", "ASCII", iascii,
strlen (iascii), (size_t) -1, ia2u_ignore, EILSEQ);
test_iconv ("ISO-10646/UTF-8//TRANSLIT//IGNORE", "ASCII", iascii,
strlen (iascii), (size_t) -1, ia2u_ignore, EILSEQ);
return 0;
}
#include <support/test-driver.c>
+50
View File
@@ -0,0 +1,50 @@
/* Test iconv behavior on UCS4 conversions with //IGNORE.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
/* Derived from BZ #26923 */
#include <errno.h>
#include <iconv.h>
#include <stdio.h>
#include <support/check.h>
static int
do_test (void)
{
iconv_t cd = iconv_open ("UTF-8//IGNORE", "ISO-10646/UCS4/");
TEST_VERIFY_EXIT (cd != (iconv_t) -1);
/*
* Convert sequence beginning with an irreversible character into buffer that
* is too small.
*/
char input[12] = "\xe1\x80\xa1" "AAAAAAAAA";
char *inptr = input;
size_t insize = sizeof (input);
char output[6];
char *outptr = output;
size_t outsize = sizeof (output);
TEST_VERIFY (iconv (cd, &inptr, &insize, &outptr, &outsize) == -1);
TEST_VERIFY (errno == E2BIG);
TEST_VERIFY_EXIT (iconv_close (cd) != -1);
return 0;
}
#include <support/test-driver.c>
+280
View File
@@ -0,0 +1,280 @@
#!/bin/bash
# Test for some known iconv(1) hangs from bug 19519, and miscellaneous
# iconv(1) program error conditions.
# Copyright (C) 2020 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
# The GNU C Library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with the GNU C Library; if not, see
# <https://www.gnu.org/licenses/>.
codir=$1
test_wrapper_env="$2"
run_program_env="$3"
# We have to have some directories in the library path.
LIBPATH=$codir:$codir/iconvdata
# How the start the iconv(1) program. $from is not defined/expanded yet.
ICONV='
$codir/elf/ld.so --library-path $LIBPATH --inhibit-rpath ${from}.so
$codir/iconv/iconv_prog
'
ICONV="$test_wrapper_env $run_program_env $ICONV"
# List of known hangs;
# Gathered by running an exhaustive 2 byte input search against glibc-2.28
hangarray=(
"\x00\x23;-c;ANSI_X3.110;UTF-8//TRANSLIT//IGNORE"
"\x00\xa1;-c;ARMSCII-8;UTF-8//TRANSLIT//IGNORE"
"\x00\xa1;-c;ASMO_449;UTF-8//TRANSLIT//IGNORE"
"\x00\x81;-c;BIG5;UTF-8//TRANSLIT//IGNORE"
"\x00\xff;-c;BIG5HKSCS;UTF-8//TRANSLIT//IGNORE"
"\x00\xff;-c;BRF;UTF-8//TRANSLIT//IGNORE"
"\x00\xff;-c;BS_4730;UTF-8//TRANSLIT//IGNORE"
"\x00\x81;-c;CP1250;UTF-8//TRANSLIT//IGNORE"
"\x00\x98;-c;CP1251;UTF-8//TRANSLIT//IGNORE"
"\x00\x81;-c;CP1252;UTF-8//TRANSLIT//IGNORE"
"\x00\x81;-c;CP1253;UTF-8//TRANSLIT//IGNORE"
"\x00\x81;-c;CP1254;UTF-8//TRANSLIT//IGNORE"
"\x00\x81;-c;CP1255;UTF-8//TRANSLIT//IGNORE"
"\x00\x81;-c;CP1257;UTF-8//TRANSLIT//IGNORE"
"\x00\x81;-c;CP1258;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;CP932;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;CSA_Z243.4-1985-1;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;CSA_Z243.4-1985-2;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;DEC-MCS;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;DIN_66003;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;DS_2089;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;EBCDIC-AT-DE;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;EBCDIC-AT-DE-A;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;EBCDIC-CA-FR;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;EBCDIC-DK-NO;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;EBCDIC-DK-NO-A;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;EBCDIC-ES;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;EBCDIC-ES-A;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;EBCDIC-ES-S;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;EBCDIC-FI-SE;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;EBCDIC-FI-SE-A;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;EBCDIC-FR;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;EBCDIC-IS-FRISS;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;EBCDIC-IT;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;EBCDIC-PT;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;EBCDIC-UK;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;EBCDIC-US;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;ES;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;ES2;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;EUC-CN;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;EUC-JISX0213;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;EUC-JP;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;EUC-JP-MS;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;EUC-KR;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;EUC-TW;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;GB18030;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;GB_1988-80;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;GBK;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;GOST_19768-74;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;GREEK7;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;GREEK7-OLD;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;GREEK-CCITT;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;HP-GREEK8;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;HP-ROMAN8;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;HP-ROMAN9;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;HP-THAI8;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;HP-TURKISH8;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;IBM038;UTF-8//TRANSLIT//IGNORE"
"\x00\x80;-c;IBM1004;UTF-8//TRANSLIT//IGNORE"
"\x00\xff;-c;IBM1008;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;IBM1046;UTF-8//TRANSLIT//IGNORE"
"\x00\x51;-c;IBM1132;UTF-8//TRANSLIT//IGNORE"
"\x00\xa0;-c;IBM1133;UTF-8//TRANSLIT//IGNORE"
"\x00\xce;-c;IBM1137;UTF-8//TRANSLIT//IGNORE"
"\x00\x80;-c;IBM1161;UTF-8//TRANSLIT//IGNORE"
"\x00\xdb;-c;IBM1162;UTF-8//TRANSLIT//IGNORE"
"\x00\x70;-c;IBM12712;UTF-8//TRANSLIT//IGNORE"
# These are known hangs that are yet to be fixed:
# "\x00\x0f;-c;IBM1364;UTF-8"
# "\x00\x0f;-c;IBM1371;UTF-8"
# "\x00\x0f;-c;IBM1388;UTF-8"
# "\x00\x0f;-c;IBM1390;UTF-8"
# "\x00\x0f;-c;IBM1399;UTF-8"
"\x00\x53;-c;IBM16804;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;IBM274;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;IBM275;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;IBM281;UTF-8//TRANSLIT//IGNORE"
"\x00\x57;-c;IBM290;UTF-8//TRANSLIT//IGNORE"
"\x00\x45;-c;IBM420;UTF-8//TRANSLIT//IGNORE"
"\x00\x68;-c;IBM423;UTF-8//TRANSLIT//IGNORE"
"\x00\x70;-c;IBM424;UTF-8//TRANSLIT//IGNORE"
"\x00\x53;-c;IBM4517;UTF-8//TRANSLIT//IGNORE"
"\x00\x53;-c;IBM4899;UTF-8//TRANSLIT//IGNORE"
"\x00\xa5;-c;IBM4909;UTF-8//TRANSLIT//IGNORE"
"\x00\xdc;-c;IBM4971;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;IBM803;UTF-8//TRANSLIT//IGNORE"
"\x00\x91;-c;IBM851;UTF-8//TRANSLIT//IGNORE"
"\x00\x9b;-c;IBM856;UTF-8//TRANSLIT//IGNORE"
"\x00\xd5;-c;IBM857;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;IBM864;UTF-8//TRANSLIT//IGNORE"
"\x00\x94;-c;IBM868;UTF-8//TRANSLIT//IGNORE"
"\x00\x94;-c;IBM869;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;IBM874;UTF-8//TRANSLIT//IGNORE"
"\x00\x6a;-c;IBM875;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;IBM880;UTF-8//TRANSLIT//IGNORE"
"\x00\x80;-c;IBM891;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;IBM903;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;IBM904;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;IBM905;UTF-8//TRANSLIT//IGNORE"
"\x00\x80;-c;IBM9066;UTF-8//TRANSLIT//IGNORE"
"\x00\x48;-c;IBM918;UTF-8//TRANSLIT//IGNORE"
"\x00\x57;-c;IBM930;UTF-8//TRANSLIT//IGNORE"
"\x00\x80;-c;IBM932;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;IBM933;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;IBM935;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;IBM937;UTF-8//TRANSLIT//IGNORE"
"\x00\x41;-c;IBM939;UTF-8//TRANSLIT//IGNORE"
"\x00\x80;-c;IBM943;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;INIS;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;INIS-8;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;INIS-CYRILLIC;UTF-8//TRANSLIT//IGNORE"
"\x00\xec;-c;ISIRI-3342;UTF-8//TRANSLIT//IGNORE"
"\x00\xec;-c;ISO_10367-BOX;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;ISO-2022-CN;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;ISO-2022-CN-EXT;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;ISO-2022-JP;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;ISO-2022-JP-2;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;ISO-2022-JP-3;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;ISO-2022-KR;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;ISO_2033;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;ISO_5427;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;ISO_5427-EXT;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;ISO_5428;UTF-8//TRANSLIT//IGNORE"
"\x00\xa4;-c;ISO_6937;UTF-8//TRANSLIT//IGNORE"
"\x00\xa0;-c;ISO_6937-2;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;ISO-8859-11;UTF-8//TRANSLIT//IGNORE"
"\x00\xa5;-c;ISO-8859-3;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;ISO-8859-6;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;ISO-8859-7;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;ISO-8859-8;UTF-8//TRANSLIT//IGNORE"
"\x00\x80;-c;ISO-IR-197;UTF-8//TRANSLIT//IGNORE"
"\x00\x80;-c;ISO-IR-209;UTF-8//TRANSLIT//IGNORE"
"\x00\x80;-c;IT;UTF-8//TRANSLIT//IGNORE"
"\x00\x80;-c;JIS_C6220-1969-RO;UTF-8//TRANSLIT//IGNORE"
"\x00\x80;-c;JIS_C6229-1984-B;UTF-8//TRANSLIT//IGNORE"
"\x00\x80;-c;JOHAB;UTF-8//TRANSLIT//IGNORE"
"\x00\x80;-c;JUS_I.B1.002;UTF-8//TRANSLIT//IGNORE"
"\x00\x80;-c;KOI-8;UTF-8//TRANSLIT//IGNORE"
"\x00\x88;-c;KOI8-T;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;KSC5636;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;LATIN-GREEK;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;LATIN-GREEK-1;UTF-8//TRANSLIT//IGNORE"
"\x00\xf6;-c;MAC-IS;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;MSZ_7795.3;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;NATS-DANO;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;NATS-SEFI;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;NC_NC00-10;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;NF_Z_62-010;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;NF_Z_62-010_1973;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;NS_4551-1;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;NS_4551-2;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;PT;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;PT2;UTF-8//TRANSLIT//IGNORE"
"\x00\x98;-c;RK1048;UTF-8//TRANSLIT//IGNORE"
"\x00\x98;-c;SEN_850200_B;UTF-8//TRANSLIT//IGNORE"
"\x00\x98;-c;SEN_850200_C;UTF-8//TRANSLIT//IGNORE"
"\x00\x80;-c;Shift_JISX0213;UTF-8//TRANSLIT//IGNORE"
"\x00\x80;-c;SJIS;UTF-8//TRANSLIT//IGNORE"
"\x00\x23;-c;T.61-8BIT;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;TIS-620;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;TSCII;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;UHC;UTF-8//TRANSLIT//IGNORE"
"\x00\xd8;-c;UNICODE;UTF-8//TRANSLIT//IGNORE"
"\x00\xdc;-c;UTF-16;UTF-8//TRANSLIT//IGNORE"
"\xdc\x00;-c;UTF-16BE;UTF-8//TRANSLIT//IGNORE"
"\x00\xdc;-c;UTF-16LE;UTF-8//TRANSLIT//IGNORE"
"\xff\xff;-c;UTF-7;UTF-8//TRANSLIT//IGNORE"
"\x00\x81;-c;WIN-SAMI-2;UTF-8//TRANSLIT//IGNORE"
)
# List of option combinations that *should* lead to an error
errorarray=(
# Converting from/to invalid character sets should cause error
"\x00\x00;;INVALID;INVALID"
"\x00\x00;;INVALID;UTF-8"
"\x00\x00;;UTF-8;INVALID"
)
# Requires $twobyte input, $c flag, $from, and $to to be set; sets $ret
execute_test ()
{
eval PROG=\"$ICONV\"
echo -en "$twobyte" \
| timeout -k 4 3 $PROG $c -f $from -t "$to" &>/dev/null
ret=$?
}
check_hangtest_result ()
{
if [ "$ret" -eq "124" ] || [ "$ret" -eq "137" ]; then # timeout/hang
result="HANG"
else
if [ "$ret" -eq "139" ]; then # segfault
result="SEGFAULT"
else
if [ "$ret" -gt "127" ]; then # unexpected error
result="UNEXPECTED"
else
result="OK"
fi
fi
fi
echo -n "$result: from: \"$from\", to: \"$to\","
echo " input \"$twobyte\", flags \"$c\""
if [ "$result" != "OK" ]; then
exit 1
fi
}
for hangcommand in "${hangarray[@]}"; do
twobyte="$(echo "$hangcommand" | cut -d";" -f 1)"
c="$(echo "$hangcommand" | cut -d";" -f 2)"
from="$(echo "$hangcommand" | cut -d";" -f 3)"
to="$(echo "$hangcommand" | cut -d";" -f 4)"
execute_test
check_hangtest_result
done
check_errtest_result ()
{
if [ "$ret" -eq "1" ]; then # we errored out as expected
result="PASS"
else
result="FAIL"
fi
echo -n "$result: from: \"$from\", to: \"$to\","
echo " input \"$twobyte\", flags \"$c\", return code $ret"
if [ "$result" != "PASS" ]; then
exit 1
fi
}
for errorcommand in "${errorarray[@]}"; do
twobyte="$(echo "$errorcommand" | cut -d";" -f 1)"
c="$(echo "$errorcommand" | cut -d";" -f 2)"
from="$(echo "$errorcommand" | cut -d";" -f 3)"
to="$(echo "$errorcommand" | cut -d";" -f 4)"
execute_test
check_errtest_result
done
+4 -1
View File
@@ -73,7 +73,8 @@ modules.so := $(addsuffix .so, $(modules))
ifeq (yes,$(build-shared))
tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \
bug-iconv10 bug-iconv11 bug-iconv12
bug-iconv10 bug-iconv11 bug-iconv12 \
bug-iconv13 bug-iconv14
ifeq ($(have-thread-library),yes)
tests += bug-iconv3
endif
@@ -316,6 +317,8 @@ $(objpfx)bug-iconv10.out: $(objpfx)gconv-modules \
$(addprefix $(objpfx),$(modules.so))
$(objpfx)bug-iconv12.out: $(objpfx)gconv-modules \
$(addprefix $(objpfx),$(modules.so))
$(objpfx)bug-iconv14.out: $(objpfx)gconv-modules \
$(addprefix $(objpfx),$(modules.so))
$(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \
$(addprefix $(objpfx),$(modules.so)) \

Some files were not shown because too many files have changed in this diff Show More