1997-09-27 01:14  Ulrich Drepper  <drepper@cygnus.com>

	* Makeconfig (extra-objs): Depend in before-compile.

	* configure.in: Locate Perl and substitute with complete path.
	* config.make.in: Add PERL for substitution.
	* elf/Makefile (routines): Add dl-addr.
	* elf/dladdr.c: Move the real code into ...
	* elf/dl-addr.c: New file.
	* elf/link.h: Add prototype for _dl_addr.

	* elf/dladdr.c (dladdr): Change address argument to be const.
	* elf/dlfcn.h: Likewise.

	* locale/C_name.c: Add _nl_POSIX_name.
	* locale/localeinfo.h: Add declaration of _nl_POSIX_name.
	* locale/findlocale.c (_nl_find_locale): Use _nl_POSIX_name.
	(_nl_remove_locale): Free name of data set.
	* locale/setlocale.c (clever_copy): Remove.
	(new_composite_name): Use _nl_C_name and _nl_POSIX_name in compare.
	(setname): Only remove old name when it is for category LC_ALL.

	Change malloc, free, realloc, and memalign hooks for glibc to take
	another parameter indicating the location of the caller.
	* malloc/malloc.c: Change hook functions and variables.
	* malloc/malloc.h: Likewise.
	* malloc/mcheck.c: Likewise.  Make sure later hooked function also
	get the original caller address.
	* malloc/mtrace.c: Likewise.
	(tr_where): If no information in _mtrace_file is given use the
	information about the caller.
	* malloc/Makefile (distribute): Replace mtrace.awk by mtrace.pl.
	Add rules to install mtrace.pl after rewriting.
	* malloc/mtrace.pl: New file.  Based on the old AWK script but
	with extended functionality.
	* malloc/mtrace.awk: Removed.

	* po/fr.po: New version.

	* string/Makefile: Do use builtins for tester.c and inl-tester.c.
	* string/tester.c: Rewrite.  Split in many small functions to not
	exceed gcc's limits.

	* sysdeps/unix/sysv/linux/syscalls.list: Add prctl.

1997-09-25  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* string/bits/string2.h (__stpcpy_small): Don't use casts as
	lvalues.

1997-09-26  Andreas Jaeger  <aj@arthur.rhein-neckar.de>

	* manual/time.texi (Formatting Date and Time): Clarify
	explanation of strftime flags a bit.
	Suggested by Robert Bihlmeyer <robbe@orcus.priv.at>.

1997-09-25 00:13  David S. Miller  <davem@tanya.rutgers.edu>

	* sysdeps/libm-ieee754/s_exp2f.c: Protect _GNU_SOURCE definition.
	Fix typo, it is FLT_MANT_DIG.

1997-09-24 18:52  H.J. Lu  <hjl@gnu.ai.mit.edu>

	* math/atest-exp2.c: Include <stdlib/gmp.h> instead of <gmp.h>.

1997-08-27 08:10  H.J. Lu  <hjl@gnu.ai.mit.edu>

	* libio/libio.h, libio/libioP.h: Support libio in libstdc++.

	* libio/libio.h (_IO_peekc): Defined as _IO_peekc_unlocked if
	_IO_MTSAFE_IO is undefined.

1997-09-24 23:27  Richard Henderson  <rth@cygnus.com>

	* elf/dl-runtime.c (fixup): Don't go through elf_machine_relplt, but
	lookup the value of the target symbol ourselves and call the new
	elf_machine_fixup_plt.  This kills the ELF_FIXUP_RETURN_VALUE hack.
	(profile_fixup): Likewise, but don't fix up the plt.
	* elf/rtld.c (_dl_main): ELF_MACHINE_RELOC_NOPLT renamed _JMP_SLOT.
	* sysdeps/alpha/dl-machine.h (ELF_MACHINE_RELOC_NOPLT): Renamed.
	(elf_alpha_fix_plt): Renamed elf_machine_fixup_plt.
	* sysdeps/i386/dl-machine.h (elf_machine_relplt): Killed.
	(ELF_MACHINE_JMP_SLOT): Renamed.
	(elf_machine_fixup_plt): New function.
	* sysdeps/m68k/dl-machine.h: Likewise.
	* sysdeps/powerpc/dl-machine.h: Likewise.
	(elf_machine_rela): Moved JMP_SLOT fixup out to elf_machine_fixup_plt.
	* sysdeps/sparc/sparc32/dl-machine.h: Likewise.
	* sysdeps/sparc/sparc64/dl-machine.h: Likewise.
	* sysdeps/stub/dl-machine.h: Update, sorta.

	* sysdeps/alpha/dl-machine.h (elf_machine_runtime_setup): Do profiling.
	(TRAMPOLINE_TEMPLATE): From the carcas of _RUNTIME_TRAMPOLINE, do
	both normal and profile code.
	(elf_machine_rela): Handle r_addend for .got and .plt too.
This commit is contained in:
Ulrich Drepper 1997-09-27 00:21:42 +00:00
parent 650425ceb4
commit a2b08ee541
41 changed files with 1425 additions and 700 deletions

View File

@ -1,3 +1,99 @@
1997-09-27 01:14 Ulrich Drepper <drepper@cygnus.com>
* Makeconfig (extra-objs): Depend in before-compile.
* configure.in: Locate Perl and substitute with complete path.
* config.make.in: Add PERL for substitution.
* elf/Makefile (routines): Add dl-addr.
* elf/dladdr.c: Move the real code into ...
* elf/dl-addr.c: New file.
* elf/link.h: Add prototype for _dl_addr.
* elf/dladdr.c (dladdr): Change address argument to be const.
* elf/dlfcn.h: Likewise.
* locale/C_name.c: Add _nl_POSIX_name.
* locale/localeinfo.h: Add declaration of _nl_POSIX_name.
* locale/findlocale.c (_nl_find_locale): Use _nl_POSIX_name.
(_nl_remove_locale): Free name of data set.
* locale/setlocale.c (clever_copy): Remove.
(new_composite_name): Use _nl_C_name and _nl_POSIX_name in compare.
(setname): Only remove old name when it is for category LC_ALL.
Change malloc, free, realloc, and memalign hooks for glibc to take
another parameter indicating the location of the caller.
* malloc/malloc.c: Change hook functions and variables.
* malloc/malloc.h: Likewise.
* malloc/mcheck.c: Likewise. Make sure later hooked function also
get the original caller address.
* malloc/mtrace.c: Likewise.
(tr_where): If no information in _mtrace_file is given use the
information about the caller.
* malloc/Makefile (distribute): Replace mtrace.awk by mtrace.pl.
Add rules to install mtrace.pl after rewriting.
* malloc/mtrace.pl: New file. Based on the old AWK script but
with extended functionality.
* malloc/mtrace.awk: Removed.
* po/fr.po: New version.
* string/Makefile: Do use builtins for tester.c and inl-tester.c.
* string/tester.c: Rewrite. Split in many small functions to not
exceed gcc's limits.
* sysdeps/unix/sysv/linux/syscalls.list: Add prctl.
1997-09-25 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* string/bits/string2.h (__stpcpy_small): Don't use casts as
lvalues.
1997-09-26 Andreas Jaeger <aj@arthur.rhein-neckar.de>
* manual/time.texi (Formatting Date and Time): Clarify
explanation of strftime flags a bit.
Suggested by Robert Bihlmeyer <robbe@orcus.priv.at>.
1997-09-25 00:13 David S. Miller <davem@tanya.rutgers.edu>
* sysdeps/libm-ieee754/s_exp2f.c: Protect _GNU_SOURCE definition.
Fix typo, it is FLT_MANT_DIG.
1997-09-24 18:52 H.J. Lu <hjl@gnu.ai.mit.edu>
* math/atest-exp2.c: Include <stdlib/gmp.h> instead of <gmp.h>.
1997-08-27 08:10 H.J. Lu <hjl@gnu.ai.mit.edu>
* libio/libio.h, libio/libioP.h: Support libio in libstdc++.
* libio/libio.h (_IO_peekc): Defined as _IO_peekc_unlocked if
_IO_MTSAFE_IO is undefined.
1997-09-24 23:27 Richard Henderson <rth@cygnus.com>
* elf/dl-runtime.c (fixup): Don't go through elf_machine_relplt, but
lookup the value of the target symbol ourselves and call the new
elf_machine_fixup_plt. This kills the ELF_FIXUP_RETURN_VALUE hack.
(profile_fixup): Likewise, but don't fix up the plt.
* elf/rtld.c (_dl_main): ELF_MACHINE_RELOC_NOPLT renamed _JMP_SLOT.
* sysdeps/alpha/dl-machine.h (ELF_MACHINE_RELOC_NOPLT): Renamed.
(elf_alpha_fix_plt): Renamed elf_machine_fixup_plt.
* sysdeps/i386/dl-machine.h (elf_machine_relplt): Killed.
(ELF_MACHINE_JMP_SLOT): Renamed.
(elf_machine_fixup_plt): New function.
* sysdeps/m68k/dl-machine.h: Likewise.
* sysdeps/powerpc/dl-machine.h: Likewise.
(elf_machine_rela): Moved JMP_SLOT fixup out to elf_machine_fixup_plt.
* sysdeps/sparc/sparc32/dl-machine.h: Likewise.
* sysdeps/sparc/sparc64/dl-machine.h: Likewise.
* sysdeps/stub/dl-machine.h: Update, sorta.
* sysdeps/alpha/dl-machine.h (elf_machine_runtime_setup): Do profiling.
(TRAMPOLINE_TEMPLATE): From the carcas of _RUNTIME_TRAMPOLINE, do
both normal and profile code.
(elf_machine_rela): Handle r_addend for .got and .plt too.
1997-09-25 00:23 Ulrich Drepper <drepper@cygnus.com>
* elf/dl-profile.c: Correct implementation.

11
FAQ
View File

@ -87,6 +87,9 @@ please let me know.
[Q24] ``I have set up /etc/nis.conf, and the Linux libc 5 with NYS
works great. But the glibc NIS+ doesn't seem to work.''
[Q25] ``After installing glibc name resolving doesn't work properly.''
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
[Q1] ``What systems does the GNU C Library run on?''
@ -686,6 +689,14 @@ it new with nisinit from the nis-tools (look at
http://www-vt.uni-paderborn.de/~kukuk/linux/nisplus.html).
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
[Q25] ``After installing glibc name resolving doesn't work properly.''
[A25] {AJ} You probable should read the manual section describing
``nsswitch.conf'' (just type `info libc "NSS Configuration File"').
The NSS configuration file is usually the culprit.
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
Answers were given by:

View File

@ -701,6 +701,9 @@ $(inst_slibdir)/libc.so: $(common-objpfx)libc.so
$(do-install-program)
endif
ifdef extra-objs
$(addprefix $(objpfx),$(extra-objs)): $(before-compile)
endif
ifneq (,$(versioned))
# Produce three sets of rules as above for all the smaller versioned libraries.

View File

@ -63,7 +63,10 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
LN_S = @LN_S@
MSGFMT = @MSGFMT@
# Script execution tools.
BASH = @BASH@
KSH = @KSH@
PERL = @PERL@
# More variables may be inserted below by configure.

112
configure vendored
View File

@ -1682,8 +1682,47 @@ else
fi
for ac_prog in perl
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1691: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
case "$PERL" in
/*)
ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
;;
*)
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
for ac_dir in $PATH; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_path_PERL="$ac_dir/$ac_word"
break
fi
done
IFS="$ac_save_ifs"
;;
esac
fi
PERL="$ac_cv_path_PERL"
if test -n "$PERL"; then
echo "$ac_t""$PERL" 1>&6
else
echo "$ac_t""no" 1>&6
fi
test -n "$PERL" && break
done
test -n "$PERL" || PERL="no"
echo $ac_n "checking for signed size_t type""... $ac_c" 1>&6
echo "configure:1687: checking for signed size_t type" >&5
echo "configure:1726: checking for signed size_t type" >&5
if eval "test \"`echo '$''{'libc_cv_signed_size_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1707,12 +1746,12 @@ EOF
fi
echo $ac_n "checking for libc-friendly stddef.h""... $ac_c" 1>&6
echo "configure:1711: checking for libc-friendly stddef.h" >&5
echo "configure:1750: checking for libc-friendly stddef.h" >&5
if eval "test \"`echo '$''{'libc_cv_friendly_stddef'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1716 "configure"
#line 1755 "configure"
#include "confdefs.h"
#define __need_size_t
#define __need_wchar_t
@ -1727,7 +1766,7 @@ size_t size; wchar_t wchar;
if (&size == NULL || &wchar == NULL) abort ();
; return 0; }
EOF
if { (eval echo configure:1731: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
if { (eval echo configure:1770: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
libc_cv_friendly_stddef=yes
else
@ -1746,7 +1785,7 @@ override stddef.h = # The installed <stddef.h> seems to be libc-friendly."
fi
echo $ac_n "checking whether we need to use -P to assemble .S files""... $ac_c" 1>&6
echo "configure:1750: checking whether we need to use -P to assemble .S files" >&5
echo "configure:1789: checking whether we need to use -P to assemble .S files" >&5
if eval "test \"`echo '$''{'libc_cv_need_minus_P'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1769,7 +1808,7 @@ asm-CPPFLAGS = -P # The assembler can't grok cpp's # line directives."
fi
echo $ac_n "checking for assembler global-symbol directive""... $ac_c" 1>&6
echo "configure:1773: checking for assembler global-symbol directive" >&5
echo "configure:1812: checking for assembler global-symbol directive" >&5
if eval "test \"`echo '$''{'libc_cv_asm_global_directive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1799,7 +1838,7 @@ EOF
fi
echo $ac_n "checking for .set assembler directive""... $ac_c" 1>&6
echo "configure:1803: checking for .set assembler directive" >&5
echo "configure:1842: checking for .set assembler directive" >&5
if eval "test \"`echo '$''{'libc_cv_asm_set_directive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1833,7 +1872,7 @@ EOF
fi
echo $ac_n "checking for .symver assembler directive""... $ac_c" 1>&6
echo "configure:1837: checking for .symver assembler directive" >&5
echo "configure:1876: checking for .symver assembler directive" >&5
if eval "test \"`echo '$''{'libc_cv_asm_symver_directive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1852,7 +1891,7 @@ fi
echo "$ac_t""$libc_cv_asm_symver_directive" 1>&6
echo $ac_n "checking for ld --version-script""... $ac_c" 1>&6
echo "configure:1856: checking for ld --version-script" >&5
echo "configure:1895: checking for ld --version-script" >&5
if eval "test \"`echo '$''{'libc_cv_ld_version_script_option'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1871,7 +1910,7 @@ EOF
if { ac_try='${CC-cc} $CFLAGS -shared -o conftest.so conftest.o
-nostartfiles -nostdlib
-Wl,--version-script,conftest.map
1>&5'; { (eval echo configure:1875: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
1>&5'; { (eval echo configure:1914: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
then
libc_cv_ld_version_script_option=yes
else
@ -1902,7 +1941,7 @@ fi
if test $elf = yes; then
echo $ac_n "checking for .previous assembler directive""... $ac_c" 1>&6
echo "configure:1906: checking for .previous assembler directive" >&5
echo "configure:1945: checking for .previous assembler directive" >&5
if eval "test \"`echo '$''{'libc_cv_asm_previous_directive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1910,7 +1949,7 @@ else
.section foo_section
.previous
EOF
if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1914: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1953: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
libc_cv_asm_previous_directive=yes
else
libc_cv_asm_previous_directive=no
@ -1926,7 +1965,7 @@ EOF
else
echo $ac_n "checking for .popsection assembler directive""... $ac_c" 1>&6
echo "configure:1930: checking for .popsection assembler directive" >&5
echo "configure:1969: checking for .popsection assembler directive" >&5
if eval "test \"`echo '$''{'libc_cv_asm_popsection_directive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1934,7 +1973,7 @@ else
.pushsection foo_section
.popsection
EOF
if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1938: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1977: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
libc_cv_asm_popsection_directive=yes
else
libc_cv_asm_popsection_directive=no
@ -1954,12 +1993,12 @@ fi
if test $elf != yes; then
echo $ac_n "checking for .init and .fini sections""... $ac_c" 1>&6
echo "configure:1958: checking for .init and .fini sections" >&5
echo "configure:1997: checking for .init and .fini sections" >&5
if eval "test \"`echo '$''{'libc_cv_have_initfini'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1963 "configure"
#line 2002 "configure"
#include "confdefs.h"
int main() {
@ -1968,7 +2007,7 @@ asm (".section .init");
asm (".text");
; return 0; }
EOF
if { (eval echo configure:1972: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
if { (eval echo configure:2011: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
libc_cv_have_initfini=yes
else
@ -1996,19 +2035,19 @@ if test $elf = yes; then
else
if test $ac_cv_prog_cc_works = yes; then
echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6
echo "configure:2000: checking for _ prefix on C symbol names" >&5
echo "configure:2039: checking for _ prefix on C symbol names" >&5
if eval "test \"`echo '$''{'libc_cv_asm_underscores'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 2005 "configure"
#line 2044 "configure"
#include "confdefs.h"
asm ("_glibc_foobar:");
int main() {
glibc_foobar ();
; return 0; }
EOF
if { (eval echo configure:2012: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
if { (eval echo configure:2051: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
libc_cv_asm_underscores=yes
else
@ -2023,17 +2062,17 @@ fi
echo "$ac_t""$libc_cv_asm_underscores" 1>&6
else
echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6
echo "configure:2027: checking for _ prefix on C symbol names" >&5
echo "configure:2066: checking for _ prefix on C symbol names" >&5
if eval "test \"`echo '$''{'libc_cv_asm_underscores'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 2032 "configure"
#line 2071 "configure"
#include "confdefs.h"
void underscore_test(void) {
return; }
EOF
if { (eval echo configure:2037: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
if { (eval echo configure:2076: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
if grep _underscore_test conftest* >/dev/null; then
rm -f conftest*
libc_cv_asm_underscores=yes
@ -2066,7 +2105,7 @@ if test $elf = yes; then
libc_cv_asm_weakext_directive=no
else
echo $ac_n "checking for assembler .weak directive""... $ac_c" 1>&6
echo "configure:2070: checking for assembler .weak directive" >&5
echo "configure:2109: checking for assembler .weak directive" >&5
if eval "test \"`echo '$''{'libc_cv_asm_weak_directive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -2089,7 +2128,7 @@ echo "$ac_t""$libc_cv_asm_weak_directive" 1>&6
if test $libc_cv_asm_weak_directive = no; then
echo $ac_n "checking for assembler .weakext directive""... $ac_c" 1>&6
echo "configure:2093: checking for assembler .weakext directive" >&5
echo "configure:2132: checking for assembler .weakext directive" >&5
if eval "test \"`echo '$''{'libc_cv_asm_weakext_directive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -2126,7 +2165,7 @@ EOF
fi
echo $ac_n "checking for ld --no-whole-archive""... $ac_c" 1>&6
echo "configure:2130: checking for ld --no-whole-archive" >&5
echo "configure:2169: checking for ld --no-whole-archive" >&5
if eval "test \"`echo '$''{'libc_cv_ld_no_whole_archive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -2137,7 +2176,7 @@ __throw () {}
EOF
if { ac_try='${CC-cc} $CFLAGS
-nostdlib -nostartfiles -Wl,--no-whole-archive
-o conftest conftest.c 1>&5'; { (eval echo configure:2141: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
-o conftest conftest.c 1>&5'; { (eval echo configure:2180: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
libc_cv_ld_no_whole_archive=yes
else
libc_cv_ld_no_whole_archive=no
@ -2148,7 +2187,7 @@ fi
echo "$ac_t""$libc_cv_ld_no_whole_archive" 1>&6
echo $ac_n "checking for gcc -fno-exceptions""... $ac_c" 1>&6
echo "configure:2152: checking for gcc -fno-exceptions" >&5
echo "configure:2191: checking for gcc -fno-exceptions" >&5
if eval "test \"`echo '$''{'libc_cv_gcc_no_exceptions'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -2159,7 +2198,7 @@ __throw () {}
EOF
if { ac_try='${CC-cc} $CFLAGS
-nostdlib -nostartfiles -fno-exceptions
-o conftest conftest.c 1>&5'; { (eval echo configure:2163: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
-o conftest conftest.c 1>&5'; { (eval echo configure:2202: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
libc_cv_gcc_no_exceptions=yes
else
libc_cv_gcc_no_exceptions=no
@ -2170,12 +2209,12 @@ fi
echo "$ac_t""$libc_cv_gcc_no_exceptions" 1>&6
echo $ac_n "checking for DWARF2 unwind info support""... $ac_c" 1>&6
echo "configure:2174: checking for DWARF2 unwind info support" >&5
echo "configure:2213: checking for DWARF2 unwind info support" >&5
if eval "test \"`echo '$''{'libc_cv_gcc_dwarf2_unwind_info'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.c <<EOF
#line 2179 "configure"
#line 2218 "configure"
static char __EH_FRAME_BEGIN__;
_start ()
{
@ -2195,7 +2234,7 @@ abort () {}
EOF
if { ac_try='${CC-cc} $CFLAGS
-nostdlib -nostartfiles
-o conftest conftest.c -lgcc >&5'; { (eval echo configure:2199: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
-o conftest conftest.c -lgcc >&5'; { (eval echo configure:2238: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
libc_cv_gcc_dwarf2_unwind_info=yes
else
libc_cv_gcc_dwarf2_unwind_info=no
@ -2253,7 +2292,7 @@ if test "$uname" = "sysdeps/generic"; then
fi
echo $ac_n "checking OS release for uname""... $ac_c" 1>&6
echo "configure:2257: checking OS release for uname" >&5
echo "configure:2296: checking OS release for uname" >&5
if eval "test \"`echo '$''{'libc_cv_uname_release'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -2275,7 +2314,7 @@ echo "$ac_t""$libc_cv_uname_release" 1>&6
uname_release="$libc_cv_uname_release"
echo $ac_n "checking OS version for uname""... $ac_c" 1>&6
echo "configure:2279: checking OS version for uname" >&5
echo "configure:2318: checking OS version for uname" >&5
if eval "test \"`echo '$''{'libc_cv_uname_version'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -2297,7 +2336,7 @@ else
fi
echo $ac_n "checking stdio selection""... $ac_c" 1>&6
echo "configure:2301: checking stdio selection" >&5
echo "configure:2340: checking stdio selection" >&5
case $stdio in
libio) cat >> confdefs.h <<\EOF
@ -2309,7 +2348,7 @@ esac
echo "$ac_t""$stdio" 1>&6
echo $ac_n "checking ldap selection""... $ac_c" 1>&6
echo "configure:2313: checking ldap selection" >&5
echo "configure:2352: checking ldap selection" >&5
case $add_ons in
*ldap*)
@ -2533,6 +2572,7 @@ s%@BASH@%$BASH%g
s%@libc_cv_have_bash2@%$libc_cv_have_bash2%g
s%@KSH@%$KSH%g
s%@libc_cv_have_ksh@%$libc_cv_have_ksh%g
s%@PERL@%$PERL%g
s%@VERSIONING@%$VERSIONING%g
s%@libc_cv_have_initfini@%$libc_cv_have_initfini%g
s%@libc_cv_ld_no_whole_archive@%$libc_cv_ld_no_whole_archive%g

View File

@ -435,6 +435,9 @@ else
fi
AC_SUBST(libc_cv_have_ksh)
AC_PATH_PROGS(PERL, perl, no)
AC_SUBST(PERL)
AC_CACHE_CHECK(for signed size_t type, libc_cv_signed_size_t, [dnl
echo '#include <stddef.h>
FOOBAR __SIZE_TYPE__ FOOBAR' > conftest.c

View File

@ -22,7 +22,7 @@ subdir := elf
headers = elf.h bits/elfclass.h bits/dlfcn.h link.h dlfcn.h
routines = $(dl-routines) dl-open dl-close dl-symbol dl-support \
enbl-secure
dl-addr enbl-secure
# The core dynamic linking functions are in libc for the static and
# profiled libraries.

85
elf/dl-addr.c Normal file
View File

@ -0,0 +1,85 @@
/* Locate the shared object symbol nearest a given address.
Copyright (C) 1996, 1997 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 Library General Public License as
published by the Free Software Foundation; either version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <stddef.h>
#include <link.h>
#include <dlfcn.h>
int
_dl_addr (const void *address, Dl_info *info)
{
const ElfW(Addr) addr = (ElfW(Addr)) address;
struct link_map *l, *match;
const ElfW(Sym) *symtab, *matchsym;
const char *strtab;
/* Find the highest-addressed object that ADDRESS is not below. */
match = NULL;
for (l = _dl_loaded; l; l = l->l_next)
if (addr >= l->l_addr && !match || match->l_addr < l->l_addr)
match = l;
if (match)
{
/* We know ADDRESS lies within MATCH if in any shared object.
Make sure it isn't past the end of MATCH's segments. */
size_t n = match->l_phnum;
do
--n;
while (match->l_phdr[n].p_type != PT_LOAD);
if (addr >= (match->l_addr +
match->l_phdr[n].p_vaddr + match->l_phdr[n].p_memsz))
/* Off the end of the highest-addressed shared object. */
return 0;
}
else
return 0;
/* Now we know what object the address lies in. */
info->dli_fname = match->l_name;
info->dli_fbase = (void *) match->l_addr;
symtab = ((void *) match->l_addr + match->l_info[DT_SYMTAB]->d_un.d_ptr);
strtab = ((void *) match->l_addr + match->l_info[DT_STRTAB]->d_un.d_ptr);
/* We assume that the string table follows the symbol table, because
there is no way in ELF to know the size of the dynamic symbol table!! */
for (matchsym = NULL; (void *) symtab < (void *) strtab; ++symtab)
if (addr >= match->l_addr + symtab->st_value && !matchsym ||
matchsym->st_value < symtab->st_value &&
ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL ||
ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)
matchsym = symtab;
if (matchsym)
{
/* We found a symbol close by. Fill in its name and exact address. */
info->dli_sname = strtab + matchsym->st_name;
info->dli_saddr = (void *) (match->l_addr + matchsym->st_value);
}
else
{
/* No symbol matches. We return only the containing object. */
info->dli_sname = NULL;
info->dli_saddr = NULL;
}
return 1;
}

View File

@ -70,37 +70,16 @@ _dl_object_relocation_scope (struct link_map *l)
#include "dynamic-link.h"
/* Figure out the right type, Rel or Rela. */
#define elf_machine_rel 1
#define elf_machine_rela 2
#if elf_machine_relplt == elf_machine_rel
# define PLTREL ElfW(Rel)
#elif elf_machine_relplt == elf_machine_rela
#if !defined ELF_MACHINE_NO_RELA || ELF_MACHINE_NO_REL
# define PLTREL ElfW(Rela)
#else
# error "dl-machine.h bug: elf_machine_relplt not rel or rela"
# define PLTREL ElfW(Rel)
#endif
#undef elf_machine_rel
#undef elf_machine_rela
#ifndef VERSYMIDX
# define VERSYMIDX(sym) (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (sym))
#endif
#ifndef ELF_FIXUP_RETURN_VALUE
#define ELF_FIXUP_RETURN_VALUE(map, result) (result)
#endif
/* We need to define the function as a local symbol so that the reference
in the trampoline code will be a local PC-relative call. Tell the
compiler not to worry that the function appears not to be called. */
static ElfW(Addr) fixup (
#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
#endif
struct link_map *l, ElfW(Word) reloc_offset)
__attribute__ ((unused));
/* This function is called through a special trampoline from the PLT the
first time each PLT entry is called. We must perform the relocation
@ -109,7 +88,7 @@ static ElfW(Addr) fixup (
to that address. Future calls will bounce directly from the PLT to the
function. */
static ElfW(Addr)
static ElfW(Addr) __attribute__ ((unused))
fixup (
#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
@ -124,57 +103,63 @@ fixup (
const PLTREL *const reloc
= (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr +
reloc_offset);
ElfW(Addr) *const rel_addr = (ElfW(Addr) *)(l->l_addr + reloc->r_offset);
const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);
ElfW(Addr) value;
/* Set up the scope to find symbols referenced by this object. */
struct link_map **scope = _dl_object_relocation_scope (l);
/* Sanity check that we're really looking at a PLT relocation. */
assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
/* Look up the target symbol. */
switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
{
const struct r_found_version *here_version;
/* This macro is used as a callback from the elf_machine_relplt code. */
#define RESOLVE(ref, version, flags) \
((version) != NULL && (version)->hash != 0 \
? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, (ref), scope, \
l->l_name, (version), (flags)) \
: _dl_lookup_symbol (strtab + (*ref)->st_name, (ref), scope, \
l->l_name, (flags)))
#include "dynamic-link.h"
/* Perform the specified relocation. */
if (l->l_info[VERSYMIDX (DT_VERSYM)])
default:
{
const ElfW(Half) *version =
(const ElfW(Half) *) (l->l_addr +
l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
ElfW(Half) ndx = version[ELFW(R_SYM) (reloc->r_info)];
const ElfW(Half) *vernum = (const ElfW(Half) *)
(l->l_addr + l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
const struct r_found_version *version = &l->l_versions[ndx];
here_version = &l->l_versions[ndx];
if (version->hash != 0)
{
value = _dl_lookup_versioned_symbol(strtab + sym->st_name,
&sym, scope, l->l_name,
version, ELF_MACHINE_JMP_SLOT);
break;
}
}
case 0:
value = _dl_lookup_symbol (strtab + sym->st_name, &sym, scope,
l->l_name, ELF_MACHINE_JMP_SLOT);
}
else
here_version = NULL;
elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
here_version, (void *) rel_addr);
}
/* Currently value contains the base load address of the object
that defines sym. Now add in the symbol offset. */
value = (sym ? value + sym->st_value : 0);
/* And now the relocation addend. */
#ifndef ELF_MACHINE_NO_RELA
if (l->l_info[DT_PLTRELSZ]->d_un.d_val == sizeof (ElfW(Rela)))
value += reloc->r_addend;
#elif ELF_MACHINE_NO_REL
value += reloc->r_addend;
#endif
/* Finally, fix up the plt itself. */
elf_machine_fixup_plt (l, reloc, rel_addr, value);
*_dl_global_scope_end = NULL;
/* Return the address that was written by the relocation. */
return ELF_FIXUP_RETURN_VALUE(l, *rel_addr);
return value;
}
#ifndef PROF
static ElfW(Addr)
profile_fixup (
#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
#endif
struct link_map *l, ElfW(Word) reloc_offset, ElfW(Addr) retaddr)
__attribute__ ((unused));
static ElfW(Addr)
static ElfW(Addr) __attribute__ ((unused))
profile_fixup (
#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
@ -182,6 +167,7 @@ profile_fixup (
struct link_map *l, ElfW(Word) reloc_offset, ElfW(Addr) retaddr)
{
void (*mcount_fct) (ElfW(Addr), ElfW(Addr)) = _dl_mcount;
const ElfW(Sym) *const symtab
= (const ElfW(Sym) *) (l->l_addr + l->l_info[DT_SYMTAB]->d_un.d_ptr);
const char *strtab =
@ -190,47 +176,57 @@ profile_fixup (
const PLTREL *const reloc
= (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr +
reloc_offset);
ElfW(Addr) result;
const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
ElfW(Addr) value;
/* Set up the scope to find symbols referenced by this object. */
struct link_map **scope = _dl_object_relocation_scope (l);
/* Sanity check that we're really looking at a PLT relocation. */
assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
/* Look up the target symbol. */
switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
{
const struct r_found_version *here_version;
/* This macro is used as a callback from the elf_machine_relplt code. */
#define RESOLVE(ref, version, flags) \
((version) != NULL && (version)->hash != 0 \
? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, (ref), scope, \
l->l_name, (version), (flags)) \
: _dl_lookup_symbol (strtab + (*ref)->st_name, (ref), scope, \
l->l_name, (flags)))
#include "dynamic-link.h"
/* Perform the specified relocation. */
if (l->l_info[VERSYMIDX (DT_VERSYM)])
default:
{
const ElfW(Half) *version =
(const ElfW(Half) *) (l->l_addr +
l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
ElfW(Half) ndx = version[ELFW(R_SYM) (reloc->r_info)];
const ElfW(Half) *vernum = (const ElfW(Half) *)
(l->l_addr + l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
const struct r_found_version *version = &l->l_versions[ndx];
here_version = &l->l_versions[ndx];
if (version->hash != 0)
{
value = _dl_lookup_versioned_symbol(strtab + sym->st_name,
&sym, scope, l->l_name,
version, ELF_MACHINE_JMP_SLOT);
break;
}
}
case 0:
value = _dl_lookup_symbol (strtab + sym->st_name, &sym, scope,
l->l_name, ELF_MACHINE_JMP_SLOT);
}
else
here_version = NULL;
elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
here_version, (void *) &result);
}
/* Currently value contains the base load address of the object
that defines sym. Now add in the symbol offset. */
value = (sym ? value + sym->st_value : 0);
/* And now the relocation addend. */
#ifndef ELF_MACHINE_NO_RELA
if (l->l_info[DT_PLTRELSZ]->d_un.d_val == sizeof (ElfW(Rela)))
value += reloc->r_addend;
#elif ELF_MACHINE_NO_REL
value += reloc->r_addend;
#endif
*_dl_global_scope_end = NULL;
(*mcount_fct) (retaddr, ELF_FIXUP_RETURN_VALUE (l, result));
(*mcount_fct) (retaddr, value);
/* Return the address that was written by the relocation. */
return ELF_FIXUP_RETURN_VALUE (l, result);
return value;
}
#endif
#endif /* PROF */
/* This macro is defined in dl-machine.h to define the entry point called

View File

@ -1,5 +1,5 @@
/* dladdr -- Locate the shared object symbol nearest a given address.
Copyright (C) 1996 Free Software Foundation, Inc.
/* Locate the shared object symbol nearest a given address.
Copyright (C) 1996, 1997 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
@ -23,63 +23,7 @@
int
dladdr (void *address, Dl_info *info)
dladdr (const void *address, Dl_info *info)
{
const ElfW(Addr) addr = (ElfW(Addr)) address;
struct link_map *l, *match;
const ElfW(Sym) *symtab, *matchsym;
const char *strtab;
/* Find the highest-addressed object that ADDRESS is not below. */
match = NULL;
for (l = _dl_loaded; l; l = l->l_next)
if (addr >= l->l_addr && !match || match->l_addr < l->l_addr)
match = l;
if (match)
{
/* We know ADDRESS lies within MATCH if in any shared object.
Make sure it isn't past the end of MATCH's segments. */
size_t n = match->l_phnum;
do
--n;
while (match->l_phdr[n].p_type != PT_LOAD);
if (addr >= (match->l_addr +
match->l_phdr[n].p_vaddr + match->l_phdr[n].p_memsz))
/* Off the end of the highest-addressed shared object. */
return 0;
}
else
return 0;
/* Now we know what object the address lies in. */
info->dli_fname = match->l_name;
info->dli_fbase = (void *) match->l_addr;
symtab = ((void *) match->l_addr + match->l_info[DT_SYMTAB]->d_un.d_ptr);
strtab = ((void *) match->l_addr + match->l_info[DT_STRTAB]->d_un.d_ptr);
/* We assume that the string table follows the symbol table, because
there is no way in ELF to know the size of the dynamic symbol table!! */
for (matchsym = NULL; (void *) symtab < (void *) strtab; ++symtab)
if (addr >= match->l_addr + symtab->st_value && !matchsym ||
matchsym->st_value < symtab->st_value &&
ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL ||
ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)
matchsym = symtab;
if (matchsym)
{
/* We found a symbol close by. Fill in its name and exact address. */
info->dli_sname = strtab + matchsym->st_name;
info->dli_saddr = (void *) (match->l_addr + matchsym->st_value);
}
else
{
/* No symbol matches. We return only the containing object. */
info->dli_sname = NULL;
info->dli_saddr = NULL;
}
return 1;
return _dl_addr (address, info);
}

View File

@ -68,7 +68,7 @@ typedef struct
__const char *dli_sname; /* Name of nearest symbol. */
void *dli_saddr; /* Exact value of nearest symbol. */
} Dl_info;
extern int dladdr __P ((void *__address, Dl_info *__info));
extern int dladdr __P ((const void *__address, Dl_info *__info));
__END_DECLS

View File

@ -27,6 +27,7 @@
#include <stddef.h>
#include <elf.h>
#include <dlfcn.h>
__BEGIN_DECLS
@ -358,6 +359,9 @@ extern ElfW(Addr) _dl_lookup_versioned_symbol_skip (const char *undef,
const struct r_found_version *version,
struct link_map *skip_this);
/* Locate shared object containing the given address. */
extern int _dl_addr (const void *address, Dl_info *info);
/* Look up symbol NAME in MAP's scope and return its run-time address. */
extern ElfW(Addr) _dl_symbol_value (struct link_map *map, const char *name);

View File

@ -671,7 +671,7 @@ of this helper program; chances are you did not intend to run this program.\n",
ElfW(Addr) loadbase = _dl_lookup_symbol (_dl_argv[i], &ref,
&_dl_default_scope[2],
"argument",
ELF_MACHINE_RELOC_NOPLT);
ELF_MACHINE_JMP_SLOT);
char buf[20], *bp;
buf[sizeof buf - 1] = '\0';
bp = _itoa (ref->st_value, &buf[sizeof buf - 1], 16, 0);

View File

@ -26,7 +26,6 @@
#ifndef _IO_STDIO_H
#define _IO_STDIO_H
#include <features.h>
#include <_G_config.h>
#define _IO_pos_t _G_fpos_t /* obsolete */
@ -76,12 +75,6 @@
# define _IO_USE_DTOA 1
#endif
#if 0
# ifdef _IO_NEED_STDARG_H
# include <stdarg.h>
# endif
#endif
#ifndef EOF
# define EOF (-1)
#endif
@ -156,7 +149,11 @@ struct _IO_jump_t; struct _IO_FILE;
/* Handle lock. */
#ifdef _IO_MTSAFE_IO
# if defined __GLIBC__ && __GLIBC__ >= 2
# include <bits/stdio-lock.h>
# else
/*# include <comthread.h>*/
# endif
#else
typedef void _IO_lock_t;
#endif
@ -290,7 +287,10 @@ extern void _IO_flockfile __P ((_IO_FILE *));
extern void _IO_funlockfile __P ((_IO_FILE *));
extern int _IO_ftrylockfile __P ((_IO_FILE *));
#ifndef _IO_MTSAFE_IO
#ifdef _IO_MTSAFE_IO
# define _IO_peekc(_fp) _IO_peekc_locked (_fp)
#else
# define _IO_peekc(_fp) _IO_peekc_unlocked (_fp)
# define _IO_flockfile(_fp) /**/
# define _IO_funlockfile(_fp) /**/
# define _IO_ftrylockfile(_fp) /**/
@ -298,8 +298,6 @@ extern int _IO_ftrylockfile __P ((_IO_FILE *));
# define _IO_cleanup_region_end(_Doit) /**/
#endif /* !_IO_MTSAFE_IO */
#define _IO_peekc(_fp) _IO_peekc_locked (_fp)
extern int _IO_vfscanf __P ((_IO_FILE *, const char *, _IO_va_list, int *));
extern int _IO_vfprintf __P ((_IO_FILE *, const char *, _IO_va_list));
extern _IO_ssize_t _IO_padn __P ((_IO_FILE *, int, _IO_ssize_t));

View File

@ -24,7 +24,14 @@
General Public License. */
#include <errno.h>
#include <bits/libc-lock.h>
#ifndef __set_errno
# define __set_errno(Val) errno = (Val)
#endif
#if defined __GLIBC__ && __GLIBC__ >= 2
# include <bits/libc-lock.h>
#else
/*# include <comthread.h>*/
#endif
#include "iolibio.h"

View File

@ -5,3 +5,4 @@
/* Name of our standard locale. */
const char _nl_C_name[] = "C";
const char _nl_POSIX_name[] = "POSIX";

View File

@ -64,7 +64,7 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len,
*name = (char *) _nl_C_name;
}
if (strcmp (*name, _nl_C_name) == 0 || strcmp (*name, "POSIX") == 0)
if (strcmp (*name, _nl_C_name) == 0 || strcmp (*name, _nl_POSIX_name) == 0)
{
/* We need not load anything. The needed data is contained in
the library itself. */
@ -203,6 +203,9 @@ _nl_remove_locale (int locale, struct locale_data *data)
ptr->decided = 0;
ptr->data = NULL;
/* Free the name. */
free ((char *) data->name);
/* Really delete the data. First delete the real data. */
if (data->mmaped)
{

View File

@ -107,8 +107,9 @@ extern const char *const _nl_category_names[LC_ALL + 1];
extern const size_t _nl_category_name_sizes[LC_ALL + 1];
extern struct locale_data * *const _nl_current[LC_ALL + 1];
/* Name of the standard locale. */
/* Name of the standard locales. */
extern const char _nl_C_name[];
extern const char _nl_POSIX_name[];
/* Extract the current CATEGORY locale's string for ITEM. */
#define _NL_CURRENT(category, item) \

View File

@ -130,24 +130,6 @@ __libc_lock_define_initialized (, __libc_setlocale_lock)
} while (0)
static inline char *
clever_copy (const char *string)
{
size_t len;
char *new;
if (strcmp (string, "C") == 0 || strcmp (string, "POSIX") == 0)
/* This return is dangerous because the returned string might be
placed in read-only memory. But everything should be set up to
handle this case. */
return (char *) _nl_C_name;
len = strlen (string) + 1;
new = (char *) malloc (len);
return new != NULL ? memcpy (new, string, len) : NULL;
}
/* Construct a new composite name. */
static inline char *
new_composite_name (int category, const char *newnames[LC_ALL])
@ -172,7 +154,8 @@ new_composite_name (int category, const char *newnames[LC_ALL])
if (same)
{
/* All the categories use the same name. */
if (strcmp (newnames[0], "C") == 0 || strcmp (newnames[0], "POSIX") == 0)
if (strcmp (newnames[0], _nl_C_name) == 0
|| strcmp (newnames[0], _nl_POSIX_name) == 0)
return (char *) _nl_C_name;
new = malloc (last_len + 1);
@ -207,8 +190,8 @@ setname (int category, const char *name)
if (_nl_current_names[category] == name)
return;
if (_nl_current_names[category] != _nl_C_name)
free ((void *) _nl_current_names[category]);
if (category == LC_ALL && _nl_current_names[category] != _nl_C_name)
free ((char *) _nl_current_names[category]);
_nl_current_names[category] = name;
}
@ -375,7 +358,10 @@ setlocale (int category, const char *locale)
goto abort_single;
/* We must not simply free a global locale since we have no
control over the usage. So we mark it as un-deletable. */
control over the usage. So we mark it as un-deletable.
Note: do ont remove the `if', it's necessary to copy with
the builtin locale data. */
if (newdata->usage_count != MAX_USAGE_COUNT)
newdata->usage_count = MAX_USAGE_COUNT;
}

View File

@ -27,7 +27,7 @@ dist-headers := malloc.h
headers := $(dist-headers) obstack.h
tests := mallocbug
distribute = thread-m.h mtrace.awk mcheck-init.c mcheck.h
distribute = thread-m.h mtrace.pl mcheck-init.c mcheck.h
# Things which get pasted together into gmalloc.c.
gmalloc-routines := malloc morecore
@ -41,6 +41,19 @@ non-lib.a := libmcheck.a
# These should be removed by `make clean'.
extra-objs = mcheck-init.o libmcheck.a
# The AWK script to analyze the output of the mtrace functions.
ifneq ($(PERL),no)
install-bin = mtrace
# The Perl script will print addresses and to do this nicely we must know
# whether we are on a 32 or 64 bit machine.
ifneq ($strip($(findstring wordsize-32,$(config-sysdirs))),)
address-width=10
else
address-width=18
endif
endif
include ../Rules
$(objpfx)libmcheck.a: $(objpfx)mcheck-init.o
@ -52,3 +65,9 @@ lib: $(objpfx)libmcheck.a
# Uncomment this for test releases. For public releases it is too expensive.
#CPPFLAGS-malloc.o += -DMALLOC_DEBUG
$(objpfx)mtrace: mtrace.pl
rm -fr %@.new
sed -e 's|@PERL@|$(PERL)|' -e 's|@XXX@|$(address-width)|' \
-e 's|@VERSION@|$(version)|' $^ > $@.new \
&& rm -fr $@ && mv $@.new $@ && chmod +x $@

View File

@ -1178,7 +1178,19 @@ static int main_trim(size_t pad);
#ifndef NO_THREADS
static int heap_trim(heap_info *heap, size_t pad);
#endif
#if defined(_LIBC) || defined(MALLOC_HOOKS)
#ifdef _LIBC
static Void_t* malloc_check(size_t sz, const Void_t *caller);
static void free_check(Void_t* mem, const Void_t *caller);
static Void_t* realloc_check(Void_t* oldmem, size_t bytes,
const Void_t *caller);
static Void_t* memalign_check(size_t alignment, size_t bytes,
const Void_t *caller);
static Void_t* malloc_starter(size_t sz, const Void_t *caller);
static void free_starter(Void_t* mem, const Void_t *caller);
static Void_t* malloc_atfork(size_t sz, const Void_t *caller);
static void free_atfork(Void_t* mem, const Void_t *caller);
#else
#ifdef MALLOC_HOOKS
static Void_t* malloc_check(size_t sz);
static void free_check(Void_t* mem);
static Void_t* realloc_check(Void_t* oldmem, size_t bytes);
@ -1188,6 +1200,7 @@ static void free_starter(Void_t* mem);
static Void_t* malloc_atfork(size_t sz);
static void free_atfork(Void_t* mem);
#endif
#endif
#else
@ -1520,11 +1533,19 @@ int __malloc_initialized = 0;
temporarily, because the `atfork' handler mechanism may use
malloc/free internally (e.g. in LinuxThreads). */
#if defined(_LIBC) || defined(MALLOC_HOOKS)
#ifdef _LIBC
static __malloc_ptr_t (*save_malloc_hook) __MALLOC_P ((size_t __size,
const __malloc_ptr_t));
static void (*save_free_hook) __MALLOC_P ((__malloc_ptr_t __ptr,
const __malloc_ptr_t));
static Void_t* save_arena;
#else
#ifdef MALLOC_HOOKS
static __malloc_ptr_t (*save_malloc_hook) __MALLOC_P ((size_t __size));
static void (*save_free_hook) __MALLOC_P ((__malloc_ptr_t __ptr));
static Void_t* save_arena;
#endif
#endif
static void
ptmalloc_lock_all __MALLOC_P((void))
@ -1639,11 +1660,15 @@ thread_atfork_static(ptmalloc_lock_all, ptmalloc_unlock_all, \
initialization routine, then do the normal work. */
static Void_t*
#ifdef _LIBC
malloc_hook_ini(size_t sz, const __malloc_ptr_t caller)
#else
#if __STD_C
malloc_hook_ini(size_t sz)
#else
malloc_hook_ini(sz) size_t sz;
#endif
#endif
{
__malloc_hook = NULL;
__realloc_hook = NULL;
@ -1653,11 +1678,15 @@ malloc_hook_ini(sz) size_t sz;
}
static Void_t*
#ifdef _LIBC
realloc_hook_ini(Void_t* ptr, size_t sz, const __malloc_ptr_t caller)
#else
#if __STD_C
realloc_hook_ini(Void_t* ptr, size_t sz)
#else
realloc_hook_ini(ptr, sz) Void_t* ptr; size_t sz;
#endif
#endif
{
__malloc_hook = NULL;
__realloc_hook = NULL;
@ -1667,11 +1696,15 @@ realloc_hook_ini(ptr, sz) Void_t* ptr; size_t sz;
}
static Void_t*
#ifdef _LIBC
memalign_hook_ini(size_t sz, size_t alignment, const __malloc_ptr_t caller)
#else
#if __STD_C
memalign_hook_ini(size_t sz, size_t alignment)
#else
memalign_hook_ini(sz, alignment) size_t sz; size_t alignment;
#endif
#endif
{
__malloc_hook = NULL;
__realloc_hook = NULL;
@ -1681,6 +1714,18 @@ memalign_hook_ini(sz, alignment) size_t sz; size_t alignment;
}
void weak_variable (*__malloc_initialize_hook) __MALLOC_P ((void)) = NULL;
#ifdef _LIBC
void weak_variable (*__free_hook) __MALLOC_P ((__malloc_ptr_t __ptr,
const __malloc_ptr_t)) = NULL;
__malloc_ptr_t weak_variable (*__malloc_hook)
__MALLOC_P ((size_t __size, const __malloc_ptr_t)) = malloc_hook_ini;
__malloc_ptr_t weak_variable (*__realloc_hook)
__MALLOC_P ((__malloc_ptr_t __ptr, size_t __size, const __malloc_ptr_t))
= realloc_hook_ini;
__malloc_ptr_t weak_variable (*__memalign_hook)
__MALLOC_P ((size_t __size, size_t __alignment, const __malloc_ptr_t))
= memalign_hook_ini;
#else
void weak_variable (*__free_hook) __MALLOC_P ((__malloc_ptr_t __ptr)) = NULL;
__malloc_ptr_t weak_variable (*__malloc_hook)
__MALLOC_P ((size_t __size)) = malloc_hook_ini;
@ -1688,6 +1733,7 @@ __malloc_ptr_t weak_variable (*__realloc_hook)
__MALLOC_P ((__malloc_ptr_t __ptr, size_t __size)) = realloc_hook_ini;
__malloc_ptr_t weak_variable (*__memalign_hook)
__MALLOC_P ((size_t __size, size_t __alignment)) = memalign_hook_ini;
#endif
void weak_variable (*__after_morecore_hook) __MALLOC_P ((void)) = NULL;
/* Activate a standard set of debugging hooks. */
@ -2489,7 +2535,11 @@ Void_t* mALLOc(bytes) size_t bytes;
if (__malloc_hook != NULL) {
Void_t* result;
#ifdef _LIBC
result = (*__malloc_hook)(bytes, __builtin_return_address (0));
#else
result = (*__malloc_hook)(bytes);
#endif
return result;
}
#endif
@ -2780,7 +2830,11 @@ void fREe(mem) Void_t* mem;
#if defined(_LIBC) || defined(MALLOC_HOOKS)
if (__free_hook != NULL) {
#ifdef _LIBC
(*__free_hook)(mem, __builtin_return_address (0));
#else
(*__free_hook)(mem);
#endif
return;
}
#endif
@ -2980,7 +3034,11 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
if (__realloc_hook != NULL) {
Void_t* result;
#ifdef _LIBC
result = (*__realloc_hook)(oldmem, bytes, __builtin_return_address (0));
#else
result = (*__realloc_hook)(oldmem, bytes);
#endif
return result;
}
#endif
@ -3242,7 +3300,12 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
if (__memalign_hook != NULL) {
Void_t* result;
#ifdef _LIBC
result = (*__memalign_hook)(alignment, bytes,
__builtin_return_address (0));
#else
result = (*__memalign_hook)(alignment, bytes);
#endif
return result;
}
#endif
@ -3413,10 +3476,14 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
#if defined(_LIBC) || defined(MALLOC_HOOKS)
if (__malloc_hook != NULL) {
sz = n * elem_size;
#ifdef _LIBC
mem = (*__malloc_hook)(sz, __builtin_return_address (0));
#else
mem = (*__malloc_hook)(sz);
#endif
if(mem == 0)
return 0;
#ifdef HAVE_MEMCPY
#ifdef HAVE_MEMSET
return memset(mem, 0, sz);
#else
while(sz > 0) ((char*)mem)[--sz] = 0; /* rather inefficient */
@ -4106,11 +4173,15 @@ mem2chunk_check(mem) Void_t* mem;
}
static Void_t*
#ifdef _LIBC
malloc_check(size_t sz, const Void_t *caller)
#else
#if __STD_C
malloc_check(size_t sz)
#else
malloc_check(sz) size_t sz;
#endif
#endif
{
mchunkptr victim;
INTERNAL_SIZE_T nb = request2size(sz + 1);
@ -4129,11 +4200,15 @@ malloc_check(sz) size_t sz;
}
static void
#ifdef _LIBC
free_check(Void_t* mem, const Void_t *caller)
#else
#if __STD_C
free_check(Void_t* mem)
#else
free_check(mem) Void_t* mem;
#endif
#endif
{
mchunkptr p;
@ -4166,16 +4241,24 @@ free_check(mem) Void_t* mem;
}
static Void_t*
#ifdef _LIBC
realloc_check(Void_t* oldmem, size_t bytes, const Void_t *caller)
#else
#if __STD_C
realloc_check(Void_t* oldmem, size_t bytes)
#else
realloc_check(oldmem, bytes) Void_t* oldmem; size_t bytes;
#endif
#endif
{
mchunkptr oldp, newp;
INTERNAL_SIZE_T nb, oldsize;
#ifdef _LIBC
if (oldmem == 0) return malloc_check(bytes, NULL);
#else
if (oldmem == 0) return malloc_check(bytes);
#endif
(void)mutex_lock(&main_arena.mutex);
oldp = mem2chunk_check(oldmem);
if(!oldp) {
@ -4187,7 +4270,11 @@ realloc_check(oldmem, bytes) Void_t* oldmem; size_t bytes;
case 2:
abort();
}
#ifdef _LIBC
return malloc_check(bytes, NULL);
#else
return malloc_check(bytes);
#endif
}
oldsize = chunksize(oldp);
@ -4240,16 +4327,24 @@ realloc_check(oldmem, bytes) Void_t* oldmem; size_t bytes;
}
static Void_t*
#ifdef _LIBC
memalign_check(size_t alignment, size_t bytes, const Void_t *caller)
#else
#if __STD_C
memalign_check(size_t alignment, size_t bytes)
#else
memalign_check(alignment, bytes) size_t alignment; size_t bytes;
#endif
#endif
{
INTERNAL_SIZE_T nb;
mchunkptr p;
#ifdef _LIBC
if (alignment <= MALLOC_ALIGNMENT) return malloc_check(bytes, NULL);
#else
if (alignment <= MALLOC_ALIGNMENT) return malloc_check(bytes);
#endif
if (alignment < MINSIZE) alignment = MINSIZE;
nb = request2size(bytes+1);
@ -4270,11 +4365,15 @@ memalign_check(alignment, bytes) size_t alignment; size_t bytes;
ptmalloc_init() hasn't completed yet. */
static Void_t*
#ifdef _LIBC
malloc_starter(size_t sz, const Void_t *caller)
#else
#if __STD_C
malloc_starter(size_t sz)
#else
malloc_starter(sz) size_t sz;
#endif
#endif
{
mchunkptr victim = chunk_alloc(&main_arena, request2size(sz));
@ -4282,11 +4381,15 @@ malloc_starter(sz) size_t sz;
}
static void
#ifdef _LIBC
free_starter(Void_t* mem, const Void_t *caller)
#else
#if __STD_C
free_starter(Void_t* mem)
#else
free_starter(mem) Void_t* mem;
#endif
#endif
{
mchunkptr p;
@ -4305,11 +4408,15 @@ free_starter(mem) Void_t* mem;
is active. */
static Void_t*
#ifdef _LIBC
malloc_atfork (size_t sz, const Void_t *caller)
#else
#if __STD_C
malloc_atfork(size_t sz)
#else
malloc_atfork(sz) size_t sz;
#endif
#endif
{
Void_t *vptr = NULL;
@ -4328,11 +4435,15 @@ malloc_atfork(sz) size_t sz;
}
static void
#ifdef _LIBC
free_atfork(Void_t* mem, const Void_t *caller)
#else
#if __STD_C
free_atfork(Void_t* mem)
#else
free_atfork(mem) Void_t* mem;
#endif
#endif
{
Void_t *vptr = NULL;
arena *ar_ptr;

View File

@ -178,8 +178,25 @@ extern __malloc_ptr_t malloc_get_state __MALLOC_P ((void));
malloc_get_state(). */
extern int malloc_set_state __MALLOC_P ((__malloc_ptr_t __ptr));
#if defined(__GLIBC__) || defined(MALLOC_HOOKS)
#ifdef __GLIBC__
/* Hooks for debugging versions. */
extern void (*__malloc_initialize_hook) __MALLOC_P ((void));
extern void (*__free_hook) __MALLOC_P ((__malloc_ptr_t __ptr,
__const __malloc_ptr_t));
extern __malloc_ptr_t (*__malloc_hook) __MALLOC_P ((size_t __size,
__const __malloc_ptr_t));
extern __malloc_ptr_t (*__realloc_hook) __MALLOC_P ((__malloc_ptr_t __ptr,
size_t __size,
__const __malloc_ptr_t));
extern __malloc_ptr_t (*__memalign_hook) __MALLOC_P ((size_t __size,
size_t __alignment,
__const __malloc_ptr_t));
extern void (*__after_morecore_hook) __MALLOC_P ((void));
/* Activate a standard set of debugging hooks. */
extern void __malloc_check_init __MALLOC_P ((void));
#else
#ifdef MALLOC_HOOKS
/* Hooks for debugging versions. */
extern void (*__malloc_initialize_hook) __MALLOC_P ((void));
extern void (*__free_hook) __MALLOC_P ((__malloc_ptr_t __ptr));
@ -192,7 +209,7 @@ extern void (*__after_morecore_hook) __MALLOC_P ((void));
/* Activate a standard set of debugging hooks. */
extern void __malloc_check_init __MALLOC_P ((void));
#endif
#endif
#ifdef __cplusplus

View File

@ -28,9 +28,10 @@
#endif
/* Old hook values. */
static void (*old_free_hook) __P ((__ptr_t ptr));
static __ptr_t (*old_malloc_hook) __P ((__malloc_size_t size));
static __ptr_t (*old_realloc_hook) __P ((__ptr_t ptr, __malloc_size_t size));
static void (*old_free_hook) __P ((__ptr_t ptr, __const __ptr_t));
static __ptr_t (*old_malloc_hook) __P ((__malloc_size_t size, const __ptr_t));
static __ptr_t (*old_realloc_hook) __P ((__ptr_t ptr, __malloc_size_t size,
__const __ptr_t));
/* Function to call when something awful happens. */
static void (*abortfunc) __P ((enum mcheck_status));
@ -91,10 +92,11 @@ checkhdr (hdr)
return status;
}
static void freehook __P ((__ptr_t));
static void freehook __P ((__ptr_t, const __ptr_t));
static void
freehook (ptr)
freehook (ptr, caller)
__ptr_t ptr;
const __ptr_t caller;
{
if (ptr)
{
@ -105,18 +107,26 @@ freehook (ptr)
ptr = (__ptr_t) hdr;
}
__free_hook = old_free_hook;
if (old_free_hook != NULL)
(*old_free_hook) (ptr, caller);
else
free (ptr);
__free_hook = freehook;
}
static __ptr_t mallochook __P ((__malloc_size_t));
static __ptr_t mallochook __P ((__malloc_size_t, const __ptr_t));
static __ptr_t
mallochook (size)
mallochook (size, caller)
__malloc_size_t size;
const __ptr_t caller;
{
struct hdr *hdr;
__malloc_hook = old_malloc_hook;
if (old_malloc_hook != NULL)
hdr = (struct hdr *) (*old_malloc_hook) (sizeof (struct hdr) + size + 1,
caller);
else
hdr = (struct hdr *) malloc (sizeof (struct hdr) + size + 1);
__malloc_hook = mallochook;
if (hdr == NULL)
@ -129,11 +139,12 @@ mallochook (size)
return (__ptr_t) (hdr + 1);
}
static __ptr_t reallochook __P ((__ptr_t, __malloc_size_t));
static __ptr_t reallochook __P ((__ptr_t, __malloc_size_t, const __ptr_t));
static __ptr_t
reallochook (ptr, size)
reallochook (ptr, size, caller)
__ptr_t ptr;
__malloc_size_t size;
const __ptr_t caller;
{
struct hdr *hdr;
__malloc_size_t osize;
@ -155,7 +166,13 @@ reallochook (ptr, size)
__free_hook = old_free_hook;
__malloc_hook = old_malloc_hook;
__realloc_hook = old_realloc_hook;
hdr = (struct hdr *) realloc ((__ptr_t) hdr, sizeof (struct hdr) + size + 1);
if (old_realloc_hook != NULL)
hdr = (struct hdr *) (*old_realloc_hook) ((__ptr_t) hdr,
sizeof (struct hdr) + size + 1,
caller);
else
hdr = (struct hdr *) realloc ((__ptr_t) hdr,
sizeof (struct hdr) + size + 1);
__free_hook = freehook;
__malloc_hook = mallochook;
__realloc_hook = reallochook;

View File

@ -1,50 +0,0 @@
#
# Awk program to analyze mtrace.c output.
#
{
if ($1 == "@") {
where = " (" $2 ")"
n = 3
} else {
where = ""
n = 1
}
if ($n == "+") {
if (allocated[$(n+1)] != "")
print "+", $(n+1), "Alloc", NR, "duplicate:", allocated[$(n+1)], wherewas[$(n+1)], where;
else {
wherewas[$(n+1)] = where;
allocated[$(n+1)] = $(n+2);
}
} else if ($n == "-") {
if (allocated[$(n+1)] != "") {
wherewas[$(n+1)] = "";
allocated[$(n+1)] = "";
if (allocated[$(n+1)] != "")
print "DELETE FAILED", $(n+1), allocated[$(n+1)];
} else
print "-", $(n+1), "Free", NR, "was never alloc'd", where;
} else if ($n == "<") {
if (allocated[$(n+1)] != "") {
wherewas[$(n+1)] = "";
allocated[$(n+1)] = "";
} else
print "-", $(n+1), "Realloc", NR, "was never alloc'd", where;
} else if ($n == ">") {
if (allocated[$(n+1)] != "")
print "+", $(n+1), "Realloc", NR, "duplicate:", allocated[$(n+1)], where;
else {
wherewas[$(n+1)] = $(n+2);
allocated[$(n+1)] = $(n+2);
}
} else if ($n == "=") {
# Ignore "= Start"
} else if ($n == "!") {
# Ignore failed realloc attempts for now
}
}
END {
for (x in allocated)
if (allocated[x] != "")
print "+", x, allocated[x], wherewas[x];
}

View File

@ -1,5 +1,5 @@
/* More debugging hooks for `malloc'.
Copyright (C) 1991, 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
Copyright (C) 1991, 92, 93, 94, 96, 97 Free Software Foundation, Inc.
Written April 2, 1991 by John Gilmore of Cygnus Support.
Based on mcheck.c by Mike Haertel.
@ -28,6 +28,10 @@
#include <bits/libc-lock.h>
#endif
#ifdef HAVE_ELF
#include <link.h>
#endif
#include <stdio.h>
#ifndef __GNU_LIBRARY__
@ -51,9 +55,12 @@ char *_mtrace_file;
int _mtrace_line;
/* Old hook values. */
static void (*tr_old_free_hook) __P ((__ptr_t ptr));
static __ptr_t (*tr_old_malloc_hook) __P ((__malloc_size_t size));
static __ptr_t (*tr_old_realloc_hook) __P ((__ptr_t ptr, __malloc_size_t size));
static void (*tr_old_free_hook) __P ((__ptr_t ptr, const __ptr_t));
static __ptr_t (*tr_old_malloc_hook) __P ((__malloc_size_t size,
const __ptr_t));
static __ptr_t (*tr_old_realloc_hook) __P ((__ptr_t ptr,
__malloc_size_t size,
const __ptr_t));
/* This function is called when the block being alloc'd, realloc'd, or
freed has an address matching the variable "mallwatch". In a debugger,
@ -66,51 +73,77 @@ tr_break ()
{
}
static void tr_where __P ((void));
static void tr_where __P ((const __ptr_t));
static void
tr_where ()
tr_where (caller)
const __ptr_t caller;
{
if (_mtrace_file)
{
fprintf (mallstream, "@ %s:%d ", _mtrace_file, _mtrace_line);
_mtrace_file = NULL;
}
else if (caller != NULL)
{
#ifdef HAVE_ELF
Dl_info info;
if (_dl_addr (caller, &info))
{
fprintf (mallstream, "@ %s%s%s%s%s[%p]",
info.dli_fname ?: "", info.dli_fname ? ":" : "",
info.dli_sname ? "(" : "",
info.dli_sname ?: "", info.dli_sname ? ") " : " ",
caller);
}
else
#endif
fprintf (mallstream, "@ [%p] ", caller);
}
}
static void tr_freehook __P ((__ptr_t));
static void tr_freehook __P ((__ptr_t, const __ptr_t));
static void
tr_freehook (ptr)
tr_freehook (ptr, caller)
__ptr_t ptr;
const __ptr_t caller;
{
tr_where ();
fprintf (mallstream, "- %p\n", ptr); /* Be sure to print it first. */
tr_where (caller);
/* Be sure to print it first. */
fprintf (mallstream, "- %p\n", ptr);
if (ptr == mallwatch)
tr_break ();
__libc_lock_lock (lock);
__free_hook = tr_old_free_hook;
if (tr_old_free_hook != NULL)
(*tr_old_free_hook) (ptr, caller);
else
free (ptr);
__free_hook = tr_freehook;
__libc_lock_unlock (lock);
}
static __ptr_t tr_mallochook __P ((__malloc_size_t));
static __ptr_t tr_mallochook __P ((__malloc_size_t, const __ptr_t));
static __ptr_t
tr_mallochook (size)
tr_mallochook (size, caller)
__malloc_size_t size;
const __ptr_t caller;
{
__ptr_t hdr;
__libc_lock_lock (lock);
__malloc_hook = tr_old_malloc_hook;
if (tr_old_malloc_hook != NULL)
hdr = (__ptr_t) (*tr_old_malloc_hook) (size, caller);
else
hdr = (__ptr_t) malloc (size);
__malloc_hook = tr_mallochook;
__libc_lock_unlock (lock);
tr_where ();
tr_where (caller);
/* We could be printing a NULL here; that's OK. */
fprintf (mallstream, "+ %p %lx\n", hdr, (unsigned long)size);
fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long)size);
if (hdr == mallwatch)
tr_break ();
@ -118,11 +151,12 @@ tr_mallochook (size)
return hdr;
}
static __ptr_t tr_reallochook __P ((__ptr_t, __malloc_size_t));
static __ptr_t tr_reallochook __P ((__ptr_t, __malloc_size_t, const __ptr_t));
static __ptr_t
tr_reallochook (ptr, size)
tr_reallochook (ptr, size, caller)
__ptr_t ptr;
__malloc_size_t size;
const __ptr_t caller;
{
__ptr_t hdr;
@ -134,6 +168,9 @@ tr_reallochook (ptr, size)
__free_hook = tr_old_free_hook;
__malloc_hook = tr_old_malloc_hook;
__realloc_hook = tr_old_realloc_hook;
if (tr_old_realloc_hook != NULL)
hdr = (__ptr_t) (*tr_old_realloc_hook) (ptr, size, caller);
else
hdr = (__ptr_t) realloc (ptr, size);
__free_hook = tr_freehook;
__malloc_hook = tr_mallochook;
@ -141,14 +178,14 @@ tr_reallochook (ptr, size)
__libc_lock_unlock (lock);
tr_where ();
tr_where (caller);
if (hdr == NULL)
/* Failed realloc. */
fprintf (mallstream, "! %p %lx\n", ptr, (unsigned long)size);
fprintf (mallstream, "! %p %#lx\n", ptr, (unsigned long)size);
else if (ptr == NULL)
fprintf (mallstream, "+ %p %lx\n", hdr, (unsigned long)size);
fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long)size);
else
fprintf (mallstream, "< %p\n> %p %lx\n", ptr, hdr, (unsigned long)size);
fprintf (mallstream, "< %p\n> %p %#lx\n", ptr, hdr, (unsigned long)size);
if (hdr == mallwatch)
tr_break ();

192
malloc/mtrace.pl Normal file
View File

@ -0,0 +1,192 @@
#! @PERL@
eval "exec @PERL@ -S $0 $*"
if 0;
# Copyright (C) 1997 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1997.
# Based on the mtrace.awk script.
# The GNU C Library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public License as
# published by the Free Software Foundation; either version 2 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
# Library General Public License for more details.
# You should have received a copy of the GNU Library General Public
# License along with the GNU C Library; see the file COPYING.LIB. If not,
# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
$VERSION = "@VERSION@";
$PACKAGE = "libc";
$progname = $0;
sub usage {
print "Usage: mtrace [OPTION]... [Binary] MtraceData\n";
print " --help print this help, then exit\n";
print " --version print version number, then exit\n";
exit 0;
}
# We expect two arguments:
# #1: the complete path to the binary
# #2: the mtrace data filename
# The usual options are also recognized.
arglist: while (@ARGV) {
if ($ARGV[0] eq "--v" || $ARGV[0] eq "--ve" || $ARGV[0] eq "--ver" ||
$ARGV[0] eq "--vers" || $ARGV[0] eq "--versi" ||
$ARGV[0] eq "--versio" || $ARGV[0] eq "--version") {
print "mtrace (GNU $PACKAGE) $VERSION\n";
print "Copyright (C) 1997 Free Software Foundation, Inc.\n";
print "This is free software; see the source for copying conditions. There is NO\n";
print "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
print "Written by Ulrich Drepper <drepper\@gnu.ai.mit.edu>\n";
exit 0;
} elsif ($ARGV[0] eq "--h" || $ARGV[0] eq "--he" || $ARGV[0] eq "--hel" ||
$ARGV[0] eq "--help") {
&usage;
} elsif ($ARGV[0] =~ /^-/) {
print "$progname: unrecognized option `$ARGV[0]'\n";
print "Try `$progname --help' for more information.\n";
exit 1;
} else {
last arglist;
}
}
if ($#ARGV == 0) {
$binary="";
$data=$ARGV[0];
} elsif ($#ARGV == 1) {
$binary=$ARGV[0];
$data=$ARGV[1];
} else {
die "Wrong number of arguments.";
}
sub location {
my $str = pop(@_);
return $str if ($str eq "");
if ($str =~ /[[](0x[^]]*)]:(.)*/) {
my $addr = $1;
my $fct = $2;
return $cache{$addr} if (exists $cache{$addr});
if ($binary ne "" && open (ADDR, "addr2line -e $binary $addr|")) {
my $line = <ADDR>;
chomp $line;
close (ADDR);
if ($line ne '??:0') {
$cache{$addr} = $line;
return $cache{$addr};
}
}
$cache{$addr} = $str = "$fct @ $addr";
} elsif ($str =~ /^[[](0x[^]]*)]$/) {
my $addr = $1;
return $cache{$addr} if (exists $cache{$addr});
if ($binary ne "" && open (ADDR, "addr2line -e $binary $addr|")) {
my $line = <ADDR>;
chomp $line;
close (ADDR);
if ($line ne '??:0') {
$cache{$addr} = $line;
return $cache{$addr};
}
}
$cache{$addr} = $str = $addr;
}
return $str;
}
$nr=0;
open(DATA, "<$data") || die "Cannot open mtrace data file";
while (<DATA>) {
my @cols = split (' ');
my $n, $where;
if ($cols[0] eq "@") {
# We have address and/or function name.
$where=$cols[1];
$n=2;
} else {
$where="";
$n=0;
}
$allocaddr=$cols[$n + 1];
$howmuch=hex($cols[$n + 2]);
++$nr;
SWITCH: {
if ($cols[$n] eq "+") {
if (defined $allocated{$allocaddr}) {
printf ("+ %#010x Alloc %d duplicate: %s %s\n",
hex($allocaddr), $nr, $wherewas{$allocaddr}, $where);
} else {
$allocated{$allocaddr}=$howmuch;
$wherewas{$allocaddr}=&location($where);
}
last SWITCH;
}
if ($cols[$n] eq "-") {
if (defined $allocated{$allocaddr}) {
undef $allocated{$allocaddr};
undef $wherewas{$allocaddr};
} else {
printf ("- %#010x Free %d was never alloc'd %s\n",
hex($allocaddr), $nr, &location($where));
}
last SWITCH;
}
if ($cols[$n] eq "<") {
if (defined $allocated{$allocaddr}) {
undef $allocated{$allocaddr};
undef $wherewas{$allocaddr};
} else {
printf ("- %#010x Realloc %d was never alloc'd %s\n",
hex($allocaddr), $nr, &location($where));
}
last SWITCH;
}
if ($cols[$n] eq ">") {
if (defined $allocated{$allocaddr}) {
printf ("+ %#010x Realloc %d duplicate: %#010x %s %s\n",
hex($allocaddr), $nr, $allocated{$allocaddr},
$wherewas{$allocaddr}, &location($where));
} else {
$allocated{$allocaddr}=$howmuch;
$wherewas{$allocaddr}=&location($where);
}
last SWITCH;
}
if ($cols[$n] eq "=") {
# Ignore "= Start".
last SWITCH;
}
if ($cols[$n] eq "!") {
# Ignore failed realloc for now.
last SWITCH;
}
}
}
close (DATA);
# Now print all remaining entries.
@addrs= keys %allocated;
if ($#addrs >= 0) {
print "\nNot freed memory:\n-----------------\n";
print ' ' x (@XXX@ - 7), "Address Size Caller\n";
foreach $addr (sort @addrs) {
if (defined $allocated{$addr}) {
printf ("%#0@XXX@x %#8x at %s\n", hex($addr), $allocated{$addr},
$wherewas{$addr});
}
}
}
exit 0;

View File

@ -695,8 +695,9 @@ time conversion (@pxref{Locales}).
Ordinary characters appearing in the @var{template} are copied to the
output string @var{s}; this can include multibyte character sequences.
Conversion specifiers are introduced by a @samp{%} character, followed
by an optional flag which can be one of the following. These flags,
which are GNU extensions, affect only the output of numbers:
by an optional flag which can be one of the following. These flags
are all GNU extensions. The first three affect only the output of
numbers:
@table @code
@item _

View File

@ -19,7 +19,7 @@
#include <stdio.h>
#include <math.h>
#include <gmp.h>
#include <stdlib/gmp.h>
#include <string.h>
#include <limits.h>
#include <assert.h>

272
po/fr.po
View File

@ -4,9 +4,9 @@
#
msgid ""
msgstr ""
"Project-Id-Version: GNU libc 2.0.3\n"
"POT-Creation-Date: 1997-03-30 19:08+0200\n"
"PO-Revision-Date: 1997-04-02 23:02 -0500\n"
"Project-Id-Version: GNU libc 2.0.5\n"
"POT-Creation-Date: 1997-08-21 04:13+0200\n"
"PO-Revision-Date: 1997-09-23 16:00 -0500\n"
"Last-Translator: Michel Robitaille <robitail@IRO.UMontreal.CA>\n"
"Language-Team: French <fr@li.org>\n"
"MIME-Version: 1.0\n"
@ -33,7 +33,7 @@ msgstr " rpcinfo [ -n no_de_port ] -t h
msgid " program vers proto port\n"
msgstr " program no_version protocole no_port\n"
#: time/zic.c:419
#: time/zic.c:421
#, c-format
msgid " (rule from \"%s\", line %d)"
msgstr " (règles de \"%s\", ligne %d)"
@ -42,22 +42,22 @@ msgstr " (r
msgid " done\n"
msgstr " complété.\n"
#: time/zic.c:416
#: time/zic.c:418
#, c-format
msgid "\"%s\", line %d: %s"
msgstr "\"%s\", ligne %d: %s."
#: time/zic.c:943
#: time/zic.c:947
#, c-format
msgid "\"Zone %s\" line and -l option are mutually exclusive"
msgstr "La ligne \"Zone %s\" et l'option -l sont mutuellement exclusives."
#: time/zic.c:951
#: time/zic.c:955
#, c-format
msgid "\"Zone %s\" line and -p option are mutually exclusive"
msgstr "La ligne \"Zone %s\" et l'option -p sont mutuellement exclusives."
#: time/zic.c:754
#: time/zic.c:758
#, c-format
msgid "%s in ruleless zone"
msgstr "%s est dans une zone sans règle."
@ -77,7 +77,7 @@ msgstr "%s%s%s:%u: %s%s erreur impr
msgid "%s%sUnknown signal %d\n"
msgstr "%s%ssignal inconnu %d.\n"
#: time/zic.c:2172
#: time/zic.c:2185
#, c-format
msgid "%s: %d did not sign extend correctly\n"
msgstr "%s: %d n'a pas fait correctement l'expansion de la valeur signée.\n"
@ -87,42 +87,42 @@ msgstr "%s: %d n'a pas fait correctement l'expansion de la valeur sign
msgid "%s: <mb_cur_max> must be greater than <mb_cur_min>\n"
msgstr "%s: <mb_cur_max> doit être plus grande que <mb_cur_min>.\n"
#: time/zic.c:1443
#: time/zic.c:1456
#, c-format
msgid "%s: Can't create %s: %s\n"
msgstr "%s: ne peut créer %s: %s.\n"
#: time/zic.c:2150
#: time/zic.c:2163
#, c-format
msgid "%s: Can't create directory %s: %s\n"
msgstr "%s: ne peut créer le répertoire %s: %s.\n"
#: time/zic.c:608
#: time/zic.c:610
#, c-format
msgid "%s: Can't link from %s to %s: %s\n"
msgstr "%s: ne peut établir un lien entre %s et %s: %s.\n"
#: time/zic.c:780
#: time/zic.c:784
#, c-format
msgid "%s: Can't open %s: %s\n"
msgstr "%s: ne peut ouvrir %s: %s.\n"
#: time/zic.c:1433
#: time/zic.c:1446
#, c-format
msgid "%s: Can't remove %s: %s\n"
msgstr "%s: ne peut enlever %s: %s.\n"
#: time/zic.c:849
#: time/zic.c:853
#, c-format
msgid "%s: Error closing %s: %s\n"
msgstr "%s: erreur lors de la fermeture de %s: %s.\n"
#: time/zic.c:842
#: time/zic.c:846
#, c-format
msgid "%s: Error reading %s\n"
msgstr "%s: erreur de lecture de %s.\n"
#: time/zic.c:1507
#: time/zic.c:1520
#, c-format
msgid "%s: Error writing %s\n"
msgstr "%s: erreur d'écriture de %s.\n"
@ -132,44 +132,44 @@ msgstr "%s: erreur d'
msgid "%s: Error writing standard output "
msgstr "%s: erreur d'écriture sur la sortie standard."
#: time/zic.c:827
#: time/zic.c:831
#, c-format
msgid "%s: Leap line in non leap seconds file %s\n"
msgstr ""
"%s: ligne de type `Leap' dans un fichier qui n'a pas\n"
"de délai en secondes %s.\n"
#: time/zic.c:357
#: time/zic.c:359
#, c-format
msgid "%s: Memory exhausted: %s\n"
msgstr "%s: mémoire épuisée: %s.\n"
#: time/zic.c:522
#: time/zic.c:524
#, c-format
msgid "%s: More than one -L option specified\n"
msgstr "%s: option -L spécifiée plus d'une fois.\n"
#: time/zic.c:482
#: time/zic.c:484
#, c-format
msgid "%s: More than one -d option specified\n"
msgstr "%s: option -d spécifiée plus d'une fois.\n"
#: time/zic.c:492
#: time/zic.c:494
#, c-format
msgid "%s: More than one -l option specified\n"
msgstr "%s: option -l spécifiée plus d'une fois.\n"
#: time/zic.c:502
#: time/zic.c:504
#, c-format
msgid "%s: More than one -p option specified\n"
msgstr "%s: option -p spécifiée plus d'une fois.\n"
#: time/zic.c:512
#: time/zic.c:514
#, c-format
msgid "%s: More than one -y option specified\n"
msgstr "%s: option -y spécifiée plus d'une fois.\n"
#: time/zic.c:1872
#: time/zic.c:1885
#, c-format
msgid "%s: command was '%s', result was %d\n"
msgstr "%s: la commande était '%s', le résultat était %d.\n"
@ -224,7 +224,7 @@ msgstr "%s: l'option `-W %s' est ambigu
msgid "%s: option requires an argument -- %c\n"
msgstr "%s: l'option requiert un paramètre -- %c.\n"
#: time/zic.c:834 time/zic.c:1246 time/zic.c:1266
#: time/zic.c:838 time/zic.c:1251 time/zic.c:1275
#, c-format
msgid "%s: panic: Invalid l_value %d\n"
msgstr "%s: panique: valeur %d de type `l_value' invalide.\n"
@ -244,7 +244,7 @@ msgstr "%s: option non reconnue `%c%s'.\n"
msgid "%s: unrecognized option `--%s'\n"
msgstr "%s: option non reconnue `--%s'.\n"
#: time/zic.c:441
#: time/zic.c:443
#, c-format
msgid ""
"%s: usage is %s [ -s ] [ -v ] [ -l localtime ] [ -p posixrules ] [ -d "
@ -545,7 +545,7 @@ msgstr "Connexion termin
msgid "Continued"
msgstr "Poursuite."
#: catgets/gencat.c:169 db/makedb.c:120 locale/programs/locale.c:187
#: catgets/gencat.c:169 db/makedb.c:120 locale/programs/locale.c:191
#: locale/programs/localedef.c:180
#, c-format
msgid ""
@ -803,11 +803,11 @@ msgstr "Appel syst
msgid "Invalid argument"
msgstr "Paramètre invalide."
#: posix/regex.c:960
#: posix/regex.c:978
msgid "Invalid back reference"
msgstr "Référence arrière invalide."
#: posix/regex.c:958
#: posix/regex.c:976
msgid "Invalid character class name"
msgstr "Nom de classe de caractères invalide."
@ -819,11 +819,11 @@ msgstr "Identit
msgid "Invalid client verifier"
msgstr "Vérificateur du client invalide."
#: posix/regex.c:957
#: posix/regex.c:975
msgid "Invalid collation character"
msgstr "Caractère de fusionnement invalide."
#: posix/regex.c:964
#: posix/regex.c:982
msgid "Invalid content of \\{\\}"
msgstr "Contenu invalide de \\{\\}"
@ -844,15 +844,15 @@ msgstr "
msgid "Invalid or incomplete multibyte or wide character"
msgstr "Chaîne multi-octets ou étendue de caractères invalide ou incomplète."
#: posix/regex.c:967
#: posix/regex.c:985
msgid "Invalid preceding regular expression"
msgstr "Expression régulière précédente invalide."
#: posix/regex.c:965
#: posix/regex.c:983
msgid "Invalid range end"
msgstr "Fin d'intervalle invalide."
#: posix/regex.c:956
#: posix/regex.c:974
msgid "Invalid regular expression"
msgstr "Expression régulière invalide."
@ -923,7 +923,7 @@ msgstr "
msgid "Machine is not on the network"
msgstr "La machine cible n'est pas sur le réseau."
#: posix/regex.c:966
#: posix/regex.c:984
msgid "Memory exhausted"
msgstr "Mémoire épuisée."
@ -1016,7 +1016,7 @@ msgstr "Aucune donn
msgid "No locks available"
msgstr "Aucun verrou disponible."
#: posix/regex.c:955
#: posix/regex.c:973
msgid "No match"
msgstr "Pas de concordance."
@ -1028,7 +1028,7 @@ msgstr "Aucun message du type d
msgid "No more records in map database"
msgstr "Aucun autre enregistrement dans la table de la base de données."
#: posix/regex.c:5324
#: posix/regex.c:5434
msgid "No previous regular expression"
msgstr "Aucune expression régulière ne précède."
@ -1096,7 +1096,7 @@ msgstr "Le r
msgid "Object is remote"
msgstr "L'objet est télé-accessible."
#: time/zic.c:1966
#: time/zic.c:1979
msgid "Odd number of quotation marks"
msgstr "Nombre impair de caractères apostrophe."
@ -1166,7 +1166,7 @@ msgstr "Permission non accord
msgid "Power failure"
msgstr "Panne d'alimentation."
#: posix/regex.c:968
#: posix/regex.c:986
msgid "Premature end of regular expression"
msgstr "Fin prématurée de l'expression régulière."
@ -1329,7 +1329,7 @@ msgstr "Le RTLD_NEXT utilis
msgid "Read-only file system"
msgstr "Système de fichiers accessible en lecture seulement."
#: posix/regex.c:969
#: posix/regex.c:987
msgid "Regular expression too big"
msgstr "Expression régulière trop grosse."
@ -1346,8 +1346,8 @@ msgid "Remove password or make file unreadable by others."
msgstr ""
"Retirer le mot de passe ou rendre les fichiers illisibles par les autres."
#: catgets/gencat.c:224 db/makedb.c:227 locale/programs/locale.c:257
#: locale/programs/localedef.c:412
#: catgets/gencat.c:224 db/makedb.c:227 locale/programs/locale.c:262
#: locale/programs/localedef.c:415
msgid "Report bugs using the `glibcbug' script to <bugs@gnu.ai.mit.edu>.\n"
msgstr ""
"Rapporter toutes anomalies via le script `glibcbug' à l'adresse:\n"
@ -1486,7 +1486,7 @@ msgstr "Erreur de relais de type streams."
msgid "Structure needs cleaning"
msgstr "La structure a besoin d'un nettoyage."
#: nis/ypclnt.c:689 nis/ypclnt.c:763 posix/regex.c:954
#: nis/ypclnt.c:689 nis/ypclnt.c:763 posix/regex.c:972
#: stdio-common/../sysdeps/gnu/errlist.c:7
msgid "Success"
msgstr "Succès."
@ -1570,7 +1570,7 @@ msgstr "Trappe de point d'arr
msgid "Trace/breakpoint trap"
msgstr "Trappe pour point d'arrêt et de trace."
#: posix/regex.c:959
#: posix/regex.c:977
msgid "Trailing backslash"
msgstr "Barre oblique en suffixe."
@ -1595,8 +1595,8 @@ msgstr "Noeud final de transport d
msgid "Transport endpoint is not connected"
msgstr "Le noeud final de transport n'est pas connecté."
#: catgets/gencat.c:208 db/makedb.c:209 locale/programs/locale.c:241
#: locale/programs/localedef.c:393
#: catgets/gencat.c:208 db/makedb.c:209 locale/programs/locale.c:246
#: locale/programs/localedef.c:396
#, c-format
msgid "Try `%s --help' for more information.\n"
msgstr "Pour en savoir davantage, faites: `%s --help'.\n"
@ -1645,19 +1645,19 @@ msgstr "Erreur syst
msgid "Unknown ypbind error"
msgstr "Erreur inconnue de ypbind."
#: posix/regex.c:962
#: posix/regex.c:980
msgid "Unmatched ( or \\("
msgstr "Échec du pairage de ( ou de \\("
#: posix/regex.c:970
#: posix/regex.c:988
msgid "Unmatched ) or \\)"
msgstr "Échec du pairage de ) ou de \\)"
#: posix/regex.c:961
#: posix/regex.c:979
msgid "Unmatched [ or [^"
msgstr "Échec du pairage de [ ou de [^"
#: posix/regex.c:963
#: posix/regex.c:981
msgid "Unmatched \\{"
msgstr "Échec du pairage de \\{."
@ -1677,7 +1677,8 @@ msgid ""
"Usage: %s [OPTION]... -o OUTPUT-FILE [INPUT-FILE]...\n"
" %s [OPTION]... [OUTPUT-FILE [INPUT-FILE]...]\n"
"Mandatory arguments to long options are mandatory for short options too.\n"
" -H, --header create C header file containing symbol definitions\n"
" -H, --header=NAME create C header file NAME containing symbol "
"definitions\n"
" -h, --help display this help and exit\n"
" --new do not use existing catalog, force new output file\n"
" -o, --output=NAME write output to file NAME\n"
@ -1729,7 +1730,7 @@ msgstr ""
" -V, --version afficher le nom et la version du logiciel\n"
"Si le FICHIER_D_ENTRÉE est -, la lecture se fait l'entrée standard.\n"
#: locale/programs/localedef.c:397
#: locale/programs/localedef.c:400
#, c-format
msgid ""
"Usage: %s [OPTION]... name\n"
@ -1767,7 +1768,7 @@ msgstr ""
"Répertoire système des tables de caractères: %s\n"
" fichiers locaux: %s\n"
#: locale/programs/locale.c:245
#: locale/programs/locale.c:250
#, c-format
msgid ""
"Usage: %s [OPTION]... name\n"
@ -1822,7 +1823,7 @@ msgstr "Valeur trop grande pour le type d
msgid "Virtual timer expired"
msgstr "Expiration de la minuterie virtuelle."
#: time/zic.c:1871
#: time/zic.c:1884
msgid "Wild result from command execution"
msgstr "Résultat anarchique résultant de l'exécution de la commande."
@ -1831,7 +1832,7 @@ msgstr "R
msgid "Window changed"
msgstr "La fenêtre a changée."
#: catgets/gencat.c:174 db/makedb.c:125 locale/programs/locale.c:192
#: catgets/gencat.c:174 db/makedb.c:125 locale/programs/locale.c:196
#: locale/programs/localedef.c:185
#, c-format
msgid "Written by %s.\n"
@ -1859,7 +1860,7 @@ msgstr "YPBINDPROC_DOMAIN: erreur inconnue.\n"
msgid "You really blew it this time"
msgstr "Vous avez vraiment tout gâcher cette fois-ci."
#: time/zic.c:1048
#: time/zic.c:1052
msgid "Zone continuation line end time is not after end time of previous line"
msgstr ""
"Temps final de la ligne de la zone de continuation est antérieur\n"
@ -1913,11 +1914,11 @@ msgstr "Mauvais propri
msgid "bad argument"
msgstr "Mauvais paramètre."
#: time/zic.c:1170
#: time/zic.c:1174
msgid "blank FROM field on Link line"
msgstr "Champ `FROM' vide dans la ligne de type `Link'."
#: time/zic.c:1174
#: time/zic.c:1178
msgid "blank TO field on Link line"
msgstr "Champ `TO' vide dans la ligne de type `Link'."
@ -1941,7 +1942,7 @@ msgstr "Diffusion: ioctl (a obtenu la valeur des fanions de l'interface)"
msgid "cache_set: victim not found"
msgstr "cache_set: victime non repérée."
#: time/zic.c:1698
#: time/zic.c:1711
msgid "can't determine time zone abbreviation to use just after until time"
msgstr ""
"Ne peut déterminer l'abréviation du fuseau horaire à utiliser\n"
@ -1952,7 +1953,7 @@ msgstr ""
msgid "can't reassign procedure number %d\n"
msgstr "Ne peut réassigner le numéro de procédure %d.\n"
#: locale/programs/localedef.c:291
#: locale/programs/localedef.c:294
#, c-format
msgid "cannot `stat' locale file `%s'"
msgstr "Ne peut effectuer l'évaluation `stat' du fichier local `%s'."
@ -1992,7 +1993,7 @@ msgstr "Ne peut ouvrir le fichier des localisations `%s'."
msgid "cannot open output file `%s'"
msgstr "Ne peut ouvrir le fichier de sortie `%s'."
#: locale/programs/locfile.c:1008
#: locale/programs/locfile.c:1020
#, c-format
msgid "cannot open output file `%s' for category `%s'"
msgstr "Ne peut ouvrir le fichier de sortie `%s' de catégorie `%s'."
@ -2001,27 +2002,27 @@ msgstr "Ne peut ouvrir le fichier de sortie `%s' de cat
msgid "cannot process order specification"
msgstr "Ne peut traiter la spécification d'ordonnancement."
#: locale/programs/locale.c:304
#: locale/programs/locale.c:444
#, c-format
msgid "cannot read character map directory `%s'"
msgstr "Ne peut lire via le répertoire de la table des caractères `%s'."
#: locale/programs/locale.c:279
#: locale/programs/locale.c:301
#, c-format
msgid "cannot read locale directory `%s'"
msgstr "Ne peut lire via le répertoire des définitions localisées `%s'."
#: locale/programs/localedef.c:313
#: locale/programs/localedef.c:316
#, c-format
msgid "cannot read locale file `%s'"
msgstr "Ne peut lire le fichier des définitions localisées `%s'."
#: locale/programs/localedef.c:338
#: locale/programs/localedef.c:341
#, c-format
msgid "cannot write output files to `%s'"
msgstr "Ne peut écrire dans les fichiers de sortie vers `%s'."
#: locale/programs/localedef.c:381
#: locale/programs/localedef.c:384
msgid "category data requested more than once: should not happen"
msgstr ""
"Catégorie de données requises plus d'une fois: n'aurait pas dû se produire."
@ -2146,7 +2147,7 @@ msgstr "Duplicit
msgid "duplicate set definition"
msgstr "Duplicité de la définition d'ensemble."
#: time/zic.c:963
#: time/zic.c:967
#, c-format
msgid "duplicate zone name %s (file \"%s\", line %d)"
msgstr "Duplicité du nom de zone %s (fichier \"%s\", ligne %d)."
@ -2197,11 +2198,11 @@ msgstr "Erreur lors de l'insertion dans la table de hachage."
msgid "expect string argument for `copy'"
msgstr "Chaîne attendue pour le paramètre de `copy'."
#: time/zic.c:854
#: time/zic.c:858
msgid "expected continuation line not found"
msgstr "Ligne de continuation attendue, non repérée."
#: locale/programs/locfile.c:1032
#: locale/programs/locfile.c:1044
#, c-format
msgid "failure while writing data for category `%s'"
msgstr "Échec durant l'écriture des données de catégorie `%s'."
@ -2260,11 +2261,11 @@ msgstr ""
msgid "get_myaddress: ioctl (get interface configuration)"
msgstr "get_myaddress: ioctl (a obtenu la configuration de l'interface)."
#: time/zic.c:1147
#: time/zic.c:1151
msgid "illegal CORRECTION field on Leap line"
msgstr "CORRECTION illégale du champ dans la ligne de type `Leap'."
#: time/zic.c:1151
#: time/zic.c:1155
msgid "illegal Rolling/Stationary field on Leap line"
msgstr "Champ `Rolling/Stationary' illégal sur la ligne de type `Leap'."
@ -2333,19 +2334,19 @@ msgstr ""
msgid "incorrectly formatted file"
msgstr "Fichier incorrectement formaté."
#: time/zic.c:811
#: time/zic.c:815
msgid "input line of unknown type"
msgstr "Ligne d'entrée de type inconnu."
#: time/zic.c:1760
#: time/zic.c:1773
msgid "internal error - addtype called with bad isdst"
msgstr "Erreur interne - addtype appellé avec un mauvais bloc isdst."
#: time/zic.c:1768
#: time/zic.c:1781
msgid "internal error - addtype called with bad ttisgmt"
msgstr "Erreur interne - addtype appellé avec un mauvais bloc ttisgmt."
#: time/zic.c:1764
#: time/zic.c:1777
msgid "internal error - addtype called with bad ttisstd"
msgstr "Erreur interne - addtype appellé avec un mauvais bloc ttisstd."
@ -2354,43 +2355,43 @@ msgstr "Erreur interne - addtype appell
msgid "internal error in %s, line %u"
msgstr "Erreur interne dans %s, ligne %u."
#: time/zic.c:1019
#: time/zic.c:1023
msgid "invalid GMT offset"
msgstr "Décalage relatif GMT invalide."
#: time/zic.c:1022
#: time/zic.c:1026
msgid "invalid abbreviation format"
msgstr "Format d'abréviation invalide."
#: time/zic.c:1112 time/zic.c:1313 time/zic.c:1327
#: time/zic.c:1116 time/zic.c:1326 time/zic.c:1340
msgid "invalid day of month"
msgstr "Jour du mois invalide."
#: time/zic.c:1270
#: time/zic.c:1279
msgid "invalid ending year"
msgstr "Année finale invalide."
#: time/zic.c:1084
#: time/zic.c:1088
msgid "invalid leaping year"
msgstr "Année bissextile invalide."
#: time/zic.c:1099 time/zic.c:1202
#: time/zic.c:1103 time/zic.c:1206
msgid "invalid month name"
msgstr "Nom de mois invalide."
#: time/zic.c:918
#: time/zic.c:922
msgid "invalid saved time"
msgstr "Temps sauvegardé invalide."
#: time/zic.c:1250
#: time/zic.c:1255
msgid "invalid starting year"
msgstr "Année initiale invalide."
#: time/zic.c:1128 time/zic.c:1230
#: time/zic.c:1132 time/zic.c:1235
msgid "invalid time of day"
msgstr "Heure du jour invalide."
#: time/zic.c:1318
#: time/zic.c:1331
msgid "invalid weekday name"
msgstr "Nom du jour de semaine invalide."
@ -2404,11 +2405,11 @@ msgstr ""
"La ligne avant l'ellipse ne doit pas contenir la définition d'une constante "
"de caractères."
#: time/zic.c:791
#: time/zic.c:795
msgid "line too long"
msgstr "Ligne trop longue."
#: locale/programs/localedef.c:285
#: locale/programs/localedef.c:288
#, c-format
msgid "locale file `%s', used in `copy' statement, not found"
msgstr ""
@ -2428,12 +2429,12 @@ msgstr "M
#: locale/programs/ld-collate.c:167 locale/programs/ld-collate.c:173
#: locale/programs/ld-collate.c:177 locale/programs/ld-collate.c:1442
#: locale/programs/ld-collate.c:1471 locale/programs/locfile.c:962
#: locale/programs/ld-collate.c:1471 locale/programs/locfile.c:974
#: locale/programs/xmalloc.c:68 posix/getconf.c:250
msgid "memory exhausted"
msgstr "Mémoire épuisée."
#: malloc/obstack.c:462
#: malloc/obstack.c:466
msgid "memory exhausted\n"
msgstr "Mémoire épuisée.\n"
@ -2453,7 +2454,7 @@ msgstr ""
msgid "missing era name in string %d in `era' field in category `%s'"
msgstr "Nom manquant dans la chaîne %d du champ `era' de catégorie `%s'."
#: time/zic.c:913
#: time/zic.c:917
msgid "nameless rule"
msgstr "Règle sans nom."
@ -2467,7 +2468,7 @@ msgstr "Le programme %d n'a jamais
msgid "no correct regular expression for field `%s' in category `%s': %s"
msgstr "Expression reguliere incorrecte du champ `%s' de catégorie `%s': %s"
#: time/zic.c:2086
#: time/zic.c:2099
msgid "no day in month matches rule"
msgstr "Pas de jour dans les règles de concordance."
@ -2479,7 +2480,7 @@ msgstr "Pas de d
msgid "no other keyword shall be specified when `copy' is used"
msgstr "Aucun autre mot clé ne doit être spécifié lorsque `copy' est utilisé."
#: locale/programs/localedef.c:344
#: locale/programs/localedef.c:347
msgid "no output file produced because warning were issued"
msgstr "Aucun fichier de sortie généré en raison d'un avertissement déjà émis."
@ -2543,7 +2544,7 @@ msgstr "rcmd:
msgid "registerrpc: out of memory\n"
msgstr "registerrpc: mémoire épuisée.\n"
#: time/zic.c:1821
#: time/zic.c:1834
msgid "repeated leap second moment"
msgstr "Répétition du délai une seconde fois."
@ -2576,7 +2577,7 @@ msgstr "rpcinfo: ne peut contacter le convertisseur de ports."
msgid "rpcinfo: can't contact portmapper: "
msgstr "rpcinfo: ne peut contacter le convertisseur de ports."
#: time/zic.c:704 time/zic.c:706
#: time/zic.c:708 time/zic.c:710
msgid "same rule name in multiple files"
msgstr "Même nom de règle dans plusieurs fichiers."
@ -2600,7 +2601,7 @@ msgstr ""
"La spécification de tri par le poids des symboles de\n"
"fusionnement n'a aucun sens."
#: time/zic.c:775
#: time/zic.c:779
msgid "standard input"
msgstr "entrée standard"
@ -2615,10 +2616,18 @@ msgstr ""
"Date initiale illégale dans la chaîne %d du champ `era'\n"
"de catégorie `%s'."
#: time/zic.c:1274
#: time/zic.c:1287
msgid "starting year greater than ending year"
msgstr "Année initiale plus grande que l'année finale."
#: time/zic.c:1261 time/zic.c:1285
msgid "starting year too high to be represented"
msgstr "Année de départ trop grance pour être représentée."
#: time/zic.c:1259 time/zic.c:1283
msgid "starting year too low to be represented"
msgstr "Année de départ trop petite pour être représentée"
#: locale/programs/ld-time.c:330
#, c-format
msgid "stopping date is illegal in string %d in `era' field in category `%s'"
@ -2626,6 +2635,10 @@ msgstr ""
"Date finale illégale dans la chaîne %d du champ `era'\\n\"\n"
"de catégorie `%s'."
#: sunrpc/svc_run.c:81
msgid "svc_run: - select failed"
msgstr "svc_run: - échec de sélection"
#: sunrpc/svc_tcp.c:201 sunrpc/svc_tcp.c:206
msgid "svc_tcp: makefd_xprt: out of memory\n"
msgstr "svc_tcp: makefd_xprt: mémoire épuisée.\n"
@ -2777,11 +2790,11 @@ msgstr "Ceci est la premi
# time/zic.c:1120A
# mro: à investiguer dans le code source
#: time/zic.c:1117
#: time/zic.c:1121
msgid "time before zero"
msgstr "Temps défini avant le zéro."
#: time/zic.c:1125 time/zic.c:1986 time/zic.c:2005
#: time/zic.c:1129 time/zic.c:1999 time/zic.c:2018
msgid "time overflow"
msgstr "Débordement du temps alloué."
@ -2797,15 +2810,15 @@ msgstr "Trop d'octets pour l'encodage des caract
msgid "too many character classes defined"
msgstr "Trop de définitions de classes de caractères."
#: time/zic.c:1815
#: time/zic.c:1828
msgid "too many leap seconds"
msgstr "Trop de délai en secondes."
#: time/zic.c:1787
#: time/zic.c:1800
msgid "too many local time types"
msgstr "Trop de types localisés pour la représentation du temps."
#: time/zic.c:1741
#: time/zic.c:1754
msgid "too many transitions?!"
msgstr "Trop de transitions définies?!"
@ -2813,7 +2826,7 @@ msgstr "Trop de transitions d
msgid "too many weights"
msgstr "Trop de poids définis."
#: time/zic.c:2109
#: time/zic.c:2122
msgid "too many, or too long, time zone abbreviations"
msgstr "Trop ou de trop longues abréviations de fuseaux horaires."
@ -2830,7 +2843,7 @@ msgstr "Probl
msgid "two lines in a row containing `...' are not allowed"
msgstr "Deux lignes consécutives contenant `...' ne sont pas permises."
#: time/zic.c:1281
#: time/zic.c:1294
msgid "typed single year"
msgstr "Une seule année fournie."
@ -2870,7 +2883,7 @@ msgstr "Ensemble inconnu `%s'."
msgid "unknown symbol `%.*s': line ignored"
msgstr "Symbole inconnu `%.*s': ligne ignorée."
#: time/zic.c:747
#: time/zic.c:751
msgid "unruly zone"
msgstr "Zone sans règle."
@ -2893,10 +2906,10 @@ msgstr "Nom de poids incomplet."
#: locale/programs/charset.c:119
msgid "upper limit in range is not smaller then lower limit"
msgstr ""
"Limite supérieure de l'intervalle n'est pas plus petite que la limite "
"inférieure."
"Limite supérieure de l'intervalle n'est pas plus petite que\n"
"la limite inférieure."
#: time/zic.c:2052
#: time/zic.c:2065
msgid "use of 2/29 in non leap-year"
msgstr "Utiliser 2/29 pour les années non-bissextiles."
@ -2919,7 +2932,7 @@ msgstr ""
#: locale/programs/charmap.c:245
msgid "value of <mb_cur_max> must be greater than the value of <mb_cur_min>"
msgstr ""
"La valeur de <mb_cur_max> doit être plus grande que la valeur de "
"La valeur de <mb_cur_max> doit être plus grande que la valeur de\n"
"<mb_cur_min>."
#: locale/programs/ld-monetary.c:139
@ -2949,7 +2962,7 @@ msgid "values for field `%s' in category `%s' must not be zero"
msgstr ""
"Les valeurs du champ `%s' de catégorie `%s' ne doivent pas être égal à zéro."
#: login/utmp_file.c:84
#: login/utmp_file.c:76
msgid "while opening UTMP file"
msgstr "durant l'ouverture du fichier UTMP."
@ -2957,6 +2970,11 @@ msgstr "durant l'ouverture du fichier UTMP."
msgid "while opening old catalog file"
msgstr "durant l'ouverture du vieux fichier du catalogue."
#: locale/programs/locale.c:341
#,
msgid "while preparing output"
msgstr "durant la préparation de la sortie"
#: db/makedb.c:354
msgid "while reading database"
msgstr "durant la lecture de la base de données."
@ -2969,23 +2987,23 @@ msgstr "durant l'
msgid "wrong number of arguments"
msgstr "Mauvais nombre de paramètres."
#: time/zic.c:1075
#: time/zic.c:1079
msgid "wrong number of fields on Leap line"
msgstr "Mauvais nombre de champs sur la ligne de type `Leap'."
#: time/zic.c:1166
#: time/zic.c:1170
msgid "wrong number of fields on Link line"
msgstr "Mauvais nombre de champs sur la ligne de type `Link'."
#: time/zic.c:909
#: time/zic.c:913
msgid "wrong number of fields on Rule line"
msgstr "Mauvais nombre de champs sur la ligne de type `Rule'."
#: time/zic.c:979
#: time/zic.c:983
msgid "wrong number of fields on Zone continuation line"
msgstr "Mauvais nombre de champs sur la ligne de type continuation de `Zone'."
#: time/zic.c:937
#: time/zic.c:941
msgid "wrong number of fields on Zone line"
msgstr "Mauvais nombre de champs sur la ligne de type `Zone'."
@ -2997,27 +3015,3 @@ msgstr ""
#: nis/ypclnt.c:823
msgid "yp_update: cannot get server address\n"
msgstr "yp_update: ne peut obtenir l'adresse du serveur.\n"
#~ msgid "unknown signal"
#~ msgstr "Signal inconnu."
#~ msgid "yp_all: clnttcp_create failed"
#~ msgstr "yp_all: échec de la fonction clnttcp_create()."
#~ msgid "character `%c' not defined while needed as default value"
#~ msgstr "Caractère `%c' non défini alors qu'attendu comme valeur par défaut."
#~ msgid "couldn't do tcp_create\n"
#~ msgstr "Ne peut exécuter tcp_create.\n"
#~ msgid "couldn't do udp_create\n"
#~ msgstr "Ne peut exécuter udp_create.\n"
#~ msgid "portmap CALLIT: cannot fork.\n"
#~ msgstr "portmap CALLIT: ne peut procéder à un clonage de type fork.\n"
#~ msgid "portmap cannot create socket"
#~ msgstr "portmap ne créer un socket"
#~ msgid "run_svc returned unexpectedly\n"
#~ msgstr "run_svc a retourné de façon imprévue.\n"

View File

@ -51,8 +51,6 @@ include ../Rules
tester-ENV = LANGUAGE=C
inl-tester-ENV = LANGUAGE=C
noinl-tester-ENV = LANGUAGE=C
CFLAGS-tester.c = -fno-builtin
CFLAGS-inl-tester.c = -fno-builtin
CFLAGS-noinl-tester.c = -fno-builtin
CFLAGS-tst-strlen.c = -fno-builtin
CFLAGS-stratcliff.c = -fno-builtin

View File

@ -226,8 +226,9 @@ __STRING2_COPY_TYPE (8);
++__dest; \
break; \
case 3: \
*((__uint16_t *) __dest)++ = \
*((__uint16_t *) __dest) = \
__STRING2_SMALL_GET16 (src, 0); \
__dest += sizeof (__uint16_t); \
*__dest = '\0'; \
break; \
case 4: \
@ -236,8 +237,9 @@ __STRING2_COPY_TYPE (8);
__dest += 3; \
break; \
case 5: \
*((__uint32_t *) __dest)++ = \
*((__uint32_t *) __dest) = \
__STRING2_SMALL_GET32 (src, 0); \
__dest += sizeof (__uint32_t); \
*__dest = '\0'; \
break; \
case 6: \

View File

@ -56,20 +56,19 @@ check (int thing, int number)
}
/* Complain if first two args don't strcmp as equal. */
void equal (const char *a, const char *b, int number)
void
equal (const char *a, const char *b, int number)
{
check(a != NULL && b != NULL && STREQ (a, b), number);
}
char one[50];
char two[50];
char *cp;
int
main (void)
void
test_strcmp (void)
{
char *cp;
/* Test strcmp first because we use it to test other things. */
it = "strcmp";
check (strcmp ("", "") == 0, 1); /* Trivial case. */
check (strcmp ("a", "a") == 0, 2); /* Identity. */
@ -115,8 +114,11 @@ main (void)
}
}
}
}
/* Test strcpy next because we need it to set up other tests. */
void
test_strcpy (void)
{
it = "strcpy";
check (strcpy (one, "abcd") == one, 1); /* Returned value. */
equal (one, "abcd", 2); /* Basic test. */
@ -132,8 +134,11 @@ main (void)
(void) strcpy (one, "");
equal (one, "", 7); /* Boundary condition. */
}
/* A closely related function is stpcpy. */
void
test_stpcpy (void)
{
it = "stpcpy";
check ((stpcpy (one, "a") - one) == 1, 1);
equal (one, "a", 2);
@ -193,10 +198,12 @@ main (void)
check ((stpcpy (stpcpy (stpcpy (one, "a"), "b"), "c") - one) == 3, 40);
equal (one, "abc", 41);
equal (one + 4, "xxx", 42);
}
/* stpncpy. */
void
test_stpncpy (void)
{
it = "stpncpy";
memset (one, 'x', sizeof (one));
check (stpncpy (one, "abc", 2) == one + 2, 1);
check (stpncpy (one, "abc", 3) == one + 3, 2);
@ -206,8 +213,11 @@ main (void)
check (one[4] == '\0' && one[5] == 'x', 6);
check (stpncpy (one, "abcd", 6) == one + 4, 7);
check (one[4] == '\0' && one[5] == '\0' && one[6] == 'x', 8);
}
/* strcat. */
void
test_strcat (void)
{
it = "strcat";
(void) strcpy (one, "ijk");
check (strcat (one, "lmn") == one, 1); /* Returned value. */
@ -233,9 +243,13 @@ main (void)
(void) strcpy (one, "");
(void) strcat (one, "cd");
equal (one, "cd", 9);
}
/* strncat - first test it as strcat, with big counts,
then test the count mechanism. */
void
test_strncat (void)
{
/* First test it as strcat, with big counts, then test the count
mechanism. */
it = "strncat";
(void) strcpy (one, "ijk");
check (strncat (one, "lmn", 99) == one, 1); /* Returned value. */
@ -271,9 +285,12 @@ main (void)
(void) strncat (one, "gh", 2);
equal (one, "abcdgh", 12); /* Count and length equal. */
}
/* strncmp - first test as strcmp with big counts,
then test count code. */
void
test_strncmp (void)
{
/* First test as strcmp with big counts, then test count code. */
it = "strncmp";
check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */
check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */
@ -288,8 +305,12 @@ main (void)
check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */
check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */
}
/* strncpy - testing is a bit different because of odd semantics. */
void
test_strncpy (void)
{
/* Testing is a bit different because of odd semantics. */
it = "strncpy";
check (strncpy (one, "abc", 4) == one, 1); /* Returned value. */
equal (one, "abc", 2); /* Did the copy go right? */
@ -326,8 +347,11 @@ main (void)
(void) strncpy (two, one, 9);
equal (two, "hi there", 14); /* Just paranoia. */
equal (one, "hi there", 15); /* Stomped on source? */
}
/* strlen. */
void
test_strlen (void)
{
it = "strlen";
check (strlen ("") == 0, 1); /* Empty. */
check (strlen ("a") == 1, 2); /* Single char. */
@ -344,8 +368,11 @@ main (void)
check (strlen (p) == 2, 4+i);
}
}
}
/* strchr. */
void
test_strchr (void)
{
it = "strchr";
check (strchr ("abcd", 'z') == NULL, 1); /* Not found. */
(void) strcpy (one, "abcd");
@ -370,9 +397,11 @@ main (void)
check (strchr (p, '/') == NULL, 9+i);
}
}
}
#if 0
/* index - just like strchr. */
void
test_index (void)
{
it = "index";
check (index ("abcd", 'z') == NULL, 1); /* Not found. */
(void) strcpy (one, "abcd");
@ -385,9 +414,11 @@ main (void)
(void) strcpy (one, "");
check (index (one, 'b') == NULL, 7); /* Empty string. */
check (index (one, '\0') == one, 8); /* NUL in empty string. */
#endif
}
/* strrchr. */
void
test_strrchr (void)
{
it = "strrchr";
check (strrchr ("abcd", 'z') == NULL, 1); /* Not found. */
(void) strcpy (one, "abcd");
@ -412,9 +443,11 @@ main (void)
check (strrchr (p, '/') == NULL, 9+i);
}
}
}
#if 0
/* rindex - just like strrchr. */
void
test_rindex (void)
{
it = "rindex";
check (rindex ("abcd", 'z') == NULL, 1); /* Not found. */
(void) strcpy (one, "abcd");
@ -427,9 +460,11 @@ main (void)
(void) strcpy (one, "");
check (rindex (one, 'b') == NULL, 7); /* Empty string. */
check (rindex (one, '\0') == one, 8); /* NUL in empty string. */
#endif
}
/* strpbrk - somewhat like strchr. */
void
test_strpbrk (void)
{
it = "strpbrk";
check(strpbrk("abcd", "z") == NULL, 1); /* Not found. */
(void) strcpy(one, "abcd");
@ -445,8 +480,11 @@ main (void)
(void) strcpy(one, "");
check(strpbrk(one, "bc") == NULL, 10); /* Empty string. */
check(strpbrk(one, "") == NULL, 11); /* Both strings empty. */
}
/* strstr - somewhat like strchr. */
void
test_strstr (void)
{
it = "strstr";
check(strstr("abcd", "z") == NULL, 1); /* Not found. */
check(strstr("abcd", "abx") == NULL, 2); /* Dead end. */
@ -469,24 +507,33 @@ main (void)
check(strstr(one, "bca") == one+2, 15); /* False start. */
(void) strcpy(one, "bbbcabbca");
check(strstr(one, "bbca") == one+1, 16); /* With overlap. */
}
/* strspn. */
void
test_strspn (void)
{
it = "strspn";
check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
check(strspn("abcba", "ab") == 2, 2); /* Partial. */
check(strspn("abc", "qx") == 0, 3); /* None. */
check(strspn("", "ab") == 0, 4); /* Null string. */
check(strspn("abc", "") == 0, 5); /* Null search list. */
}
/* strcspn. */
void
test_strcspn (void)
{
it = "strcspn";
check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
check(strcspn("abc", "abc") == 0, 3); /* None. */
check(strcspn("", "ab") == 0, 4); /* Null string. */
check(strcspn("abc", "") == 3, 5); /* Null search list. */
}
/* strtok - the hard one. */
void
test_strtok (void)
{
it = "strtok";
(void) strcpy(one, "first, second, third");
equal(strtok(one, ", "), "first", 1); /* Basic test. */
@ -532,8 +579,11 @@ main (void)
equal(one, "a", 31); /* Stomped old tokens? */
equal(one+2, "b", 32);
equal(one+4, "c", 33);
}
/* strtok_r. */
void
test_strtok_r (void)
{
it = "strtok_r";
(void) strcpy(one, "first, second, third");
equal(strtok_r(one, ", ", &cp), "first", 1); /* Basic test. */
@ -579,8 +629,11 @@ main (void)
equal(one, "a", 31); /* Stomped old tokens? */
equal(one+2, "b", 32);
equal(one+4, "c", 33);
}
/* strsep. */
void
test_strsep (void)
{
it = "strsep";
cp = strcpy(one, "first, second, third");
equal(strsep(&cp, ", "), "first", 1); /* Basic test. */
@ -640,7 +693,21 @@ main (void)
equal(one+2, "b", 45);
equal(one+4, "c", 46);
/* memcmp. */
{
char text[] = "This,is,a,test";
char *list = text;
it = "strsep";
check (!strcmp ("This", strsep (&list, ",")), 1);
check (!strcmp ("is", strsep (&list, ",")), 2);
check (!strcmp ("a", strsep (&list, ",")), 3);
check (!strcmp ("test", strsep (&list, ",")), 4);
check (strsep (&list, ",") == NULL, 5);
}
}
void
test_memcmp (void)
{
it = "memcmp";
check(memcmp("a", "a", 1) == 0, 1); /* Identity. */
check(memcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
@ -650,8 +717,11 @@ main (void)
check(memcmp("a\203", "a\003", 2) > 0, 6);
check(memcmp("abce", "abcd", 3) == 0, 7); /* Count limited. */
check(memcmp("abc", "def", 0) == 0, 8); /* Zero count. */
}
/* memchr. */
void
test_memchr (void)
{
it = "memchr";
check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */
(void) strcpy(one, "abcd");
@ -690,8 +760,11 @@ main (void)
}
}
}
}
/* memcpy - need not work for overlap. */
void
test_memcpy (void)
{
it = "memcpy";
check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */
equal(one, "abc", 2); /* Did the copy go right? */
@ -709,8 +782,11 @@ main (void)
(void) memcpy(two, one, 9);
equal(two, "hi there", 5); /* Just paranoia. */
equal(one, "hi there", 6); /* Stomped on source? */
}
/* memmove - must work on overlap. */
void
test_memmove (void)
{
it = "memmove";
check(memmove(one, "abc", 4) == one, 1); /* Returned value. */
equal(one, "abc", 2); /* Did the copy go right? */
@ -740,11 +816,15 @@ main (void)
(void) strcpy(one, "abcdefgh");
(void) memmove(one, one, 9);
equal(one, "abcdefgh", 9); /* 100% overlap. */
}
/* memccpy - first test like memcpy, then the search part
The SVID, the only place where memccpy is mentioned, says
overlap might fail, so we don't try it. Besides, it's hard
to see the rationale for a non-left-to-right memccpy. */
void
test_memccpy (void)
{
/* First test like memcpy, then the search part The SVID, the only
place where memccpy is mentioned, says overlap might fail, so we
don't try it. Besides, it's hard to see the rationale for a
non-left-to-right memccpy. */
it = "memccpy";
check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */
equal(one, "abc", 2); /* Did the copy go right? */
@ -778,8 +858,11 @@ main (void)
(void) strcpy(one, "xyz");
check(memccpy(two, one, 'x', 1) == two+1, 14); /* Singleton. */
equal(two, "xbcdlebee", 15);
}
/* memset. */
void
test_memset (void)
{
it = "memset";
(void) strcpy(one, "abcdefgh");
check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */
@ -831,9 +914,13 @@ main (void)
check(0,7+i+j*256+(c != 0)*256*256);
}
}
}
/* bcopy - much like memcpy.
Berklix manual is silent about overlap, so don't test it. */
void
test_bcopy (void)
{
/* Much like memcpy. Berklix manual is silent about overlap, so
don't test it. */
it = "bcopy";
(void) bcopy("abc", one, 4);
equal(one, "abc", 1); /* Simple copy. */
@ -851,8 +938,11 @@ main (void)
(void) bcopy(one, two, 9);
equal(two, "hi there", 4); /* Just paranoia. */
equal(one, "hi there", 5); /* Stomped on source? */
}
/* bzero. */
void
test_bzero (void)
{
it = "bzero";
(void) strcpy(one, "abcdef");
bzero(one+2, 2);
@ -863,9 +953,11 @@ main (void)
(void) strcpy(one, "abcdef");
bzero(one+2, 0);
equal(one, "abcdef", 4); /* Zero-length copy. */
}
#if 0
/* bcmp - somewhat like memcmp. */
void
test_bcmp (void)
{
it = "bcmp";
check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
@ -874,30 +966,114 @@ main (void)
check(bcmp("alph", "beta", 4) != 0, 5);
check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
#endif
}
{
char text[] = "This,is,a,test";
char *list = text;
it = "strsep";
check (!strcmp ("This", strsep (&list, ",")), 1);
check (!strcmp ("is", strsep (&list, ",")), 2);
check (!strcmp ("a", strsep (&list, ",")), 3);
check (!strcmp ("test", strsep (&list, ",")), 4);
check (strsep (&list, ",") == NULL, 5);
}
/* strerror - VERY system-dependent. */
{
void
test_strerror (void)
{
int f;
it = "strerror";
f = __open("/", O_WRONLY); /* Should always fail. */
check(f < 0 && errno > 0 && errno < _sys_nerr, 1);
equal(strerror(errno), _sys_errlist[errno], 2);
}
}
{
int
main (void)
{
int status;
/* Test strcmp first because we use it to test other things. */
test_strcmp ();
/* Test strcpy next because we need it to set up other tests. */
test_strcpy ();
/* A closely related function is stpcpy. */
test_stpcpy ();
/* stpncpy. */
test_stpncpy ();
/* strcat. */
test_strcat ();
/* strncat. */
test_strncat ();
/* strncmp. */
test_strncmp ();
/* strncpy. */
test_strncpy ();
/* strlen. */
test_strlen ();
/* strchr. */
test_strchr ();
/* index - just like strchr. */
test_index ();
/* strrchr. */
test_strrchr ();
/* rindex - just like strrchr. */
test_rindex ();
/* strpbrk - somewhat like strchr. */
test_strpbrk ();
/* strstr - somewhat like strchr. */
test_strstr ();
/* strspn. */
test_strspn ();
/* strcspn. */
test_strcspn ();
/* strtok - the hard one. */
test_strtok ();
/* strtok_r. */
test_strtok_r ();
/* strsep. */
test_strsep ();
/* memcmp. */
test_memcmp ();
/* memchr. */
test_memchr ();
/* memcpy - need not work for overlap. */
test_memcpy ();
/* memmove - must work on overlap. */
test_memmove ();
/* memccpy. */
test_memccpy ();
/* memset. */
test_memset ();
/* bcopy. */
test_bcopy ();
/* bzero. */
test_bzero ();
/* bcmp - somewhat like memcmp. */
test_bcmp ();
/* strerror - VERY system-dependent. */
test_strerror ();
if (errors == 0)
{
status = EXIT_SUCCESS;
@ -909,5 +1085,4 @@ main (void)
printf("%Zd errors.\n", errors);
}
exit(status);
}
}

View File

@ -91,6 +91,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
{
Elf64_Addr plt;
extern void _dl_runtime_resolve (void);
extern void _dl_runtime_profile (void);
if (l->l_info[DT_JMPREL] && lazy)
{
@ -100,7 +101,14 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
plt = l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr;
/* This function will be called to perform the relocation. */
if (!profile)
*(Elf64_Addr *)(plt + 16) = (Elf64_Addr) &_dl_runtime_resolve;
else
{
*(Elf64_Addr *)(plt + 16) = (Elf64_Addr) &_dl_runtime_profile;
/* Say that we really want profiling and the timers are started. */
_dl_profile_map = l;
}
/* Identify this shared object */
*(Elf64_Addr *)(plt + 24) = (Elf64_Addr) l;
@ -115,11 +123,10 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
/* This code is used in dl-runtime.c to call the `fixup' function
and then redirect to the address it returns. */
#define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ( \
"/* Trampoline for _dl_runtime_resolver */
.globl _dl_runtime_resolve
.ent _dl_runtime_resolve
_dl_runtime_resolve:
#define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name, IMB) asm ( "\
.globl " #tramp_name "
.ent " #tramp_name "
" #tramp_name ":
lda $sp, -168($sp)
.frame $sp, 168, $26
/* Preserve all registers that C normally doesn't. */
@ -146,18 +153,20 @@ _dl_runtime_resolve:
stq $29, 160($sp)
.mask 0x27ff01ff, -168
/* Set up our $gp */
br $gp, 0f
0: ldgp $gp, 0($gp)
br $gp, .+4
ldgp $gp, 0($gp)
.prologue 1
/* Set up the arguments for _dl_runtime_resolve. */
/* Set up the arguments for fixup: */
/* $16 = link_map out of plt0 */
/* $17 = offset of reloc entry = ($28 - $27 - 20) /12 * 24 */
/* $18 = return address */
subq $28, $27, $17
ldq $16, 8($27)
subq $17, 20, $17
mov $26, $18
addq $17, $17, $17
/* Do the fixup */
bsr $26, fixup..ng
bsr $26, " #fixup_name "..ng
/* Move the destination address into position. */
mov $0, $27
/* Restore program registers. */
@ -183,14 +192,21 @@ _dl_runtime_resolve:
ldq $25, 152($sp)
ldq $29, 160($sp)
/* Flush the Icache after having modified the .plt code. */
imb
" #IMB "
/* Clean up and turn control to the destination */
lda $sp, 168($sp)
jmp $31, ($27)
.end _dl_runtime_resolve");
.end " #tramp_name)
/* The PLT uses Elf64_Rela relocs. */
#define elf_machine_relplt elf_machine_rela
#ifndef PROF
#define ELF_MACHINE_RUNTIME_TRAMPOLINE \
TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup, imb); \
TRAMPOLINE_TEMPLATE (_dl_runtime_profile, profile_fixup, #nop);
#else
#define ELF_MACHINE_RUNTIME_TRAMPOLINE \
TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \
strong_alias (_dl_runtime_resolve, _dl_runtime_profile);
#endif
/* Initial entry point code for the dynamic linker.
The C function `_dl_start' is the real entry point;
@ -255,37 +271,31 @@ _dl_start_user:
#define elf_machine_lookup_noexec_p(type) (0)
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
#define ELF_MACHINE_RELOC_NOPLT R_ALPHA_JMP_SLOT
#define ELF_MACHINE_JMP_SLOT R_ALPHA_JMP_SLOT
/* The alpha never uses Elf64_Rel relocations. */
#define ELF_MACHINE_NO_REL 1
#endif /* !dl_machine_h */
#ifdef RESOLVE
/* Fix up the instructions of a PLT entry to invoke the function
rather than the dynamic linker. */
static inline void
elf_alpha_fix_plt(struct link_map *l,
const Elf64_Rela *reloc,
Elf64_Addr got_addr,
Elf64_Addr value)
elf_machine_fixup_plt(struct link_map *l, const Elf64_Rela *reloc,
Elf64_Addr *got_addr, Elf64_Addr value)
{
const Elf64_Rela *rela_plt;
Elf64_Word *plte;
long edisp;
/* Store the value we are going to load. */
*got_addr = value;
/* Recover the PLT entry address by calculating reloc's index into the
.rela.plt, and finding that entry in the .plt. */
rela_plt = (void *)(l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr);
plte = (void *)(l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr + 32);
plte += 3 * (reloc - rela_plt);
/* Find the displacement from the plt entry to the function. */
edisp = (long)(value - (Elf64_Addr)&plte[3]) / 4;
if (edisp >= -0x100000 && edisp < 0x100000)
@ -299,7 +309,7 @@ elf_alpha_fix_plt(struct link_map *l,
lo = (short)hi;
hi = (hi - lo) >> 16;
/* Emit "lda $27,L($27)" */
/* Emit "lda $27,lo($27)" */
plte[1] = 0x237b0000 | (lo & 0xffff);
/* Emit "br $31,function" */
@ -309,7 +319,7 @@ elf_alpha_fix_plt(struct link_map *l,
committed to memory before the first is overwritten. */
__asm__ __volatile__("wmb" : : : "memory");
/* Emit "ldah $27,H($27)" */
/* Emit "ldah $27,hi($27)" */
plte[0] = 0x277b0000 | (hi & 0xffff);
}
else
@ -319,11 +329,11 @@ elf_alpha_fix_plt(struct link_map *l,
into the cache. */
int hi, lo;
hi = got_addr - (Elf64_Addr)&plte[0];
hi = (Elf64_Addr)got_addr - (Elf64_Addr)&plte[0];
lo = (short)hi;
hi = (hi - lo) >> 16;
/* Emit "ldq $27,L($27)" */
/* Emit "ldq $27,lo($27)" */
plte[1] = 0xa77b0000 | (lo & 0xffff);
/* Emit "jmp $31,($27)" */
@ -333,7 +343,7 @@ elf_alpha_fix_plt(struct link_map *l,
committed to memory before the first is overwritten. */
__asm__ __volatile__("wmb" : : : "memory");
/* Emit "ldah $27,H($27)" */
/* Emit "ldah $27,hi($27)" */
plte[0] = 0x277b0000 | (hi & 0xffff);
}
@ -343,6 +353,10 @@ elf_alpha_fix_plt(struct link_map *l,
hasn't made it into Icache yet, so there's nothing to clean up. */
}
#endif /* !dl_machine_h */
#ifdef RESOLVE
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
MAP is the object containing the reloc. */
static inline void
@ -382,14 +396,12 @@ elf_machine_rela (struct link_map *map,
loadbase = RESOLVE (&sym, version, r_type);
sym_value = sym ? loadbase + sym->st_value : 0;
sym_value += reloc->r_addend;
if (r_type == R_ALPHA_GLOB_DAT)
*reloc_addr = sym_value;
else if (r_type == R_ALPHA_JMP_SLOT)
{
*reloc_addr = sym_value;
elf_alpha_fix_plt (map, reloc, (Elf64_Addr) reloc_addr, sym_value);
}
elf_machine_fixup_plt (map, reloc, reloc_addr, sym_value);
else if (r_type == R_ALPHA_REFQUAD)
{
sym_value += *reloc_addr;
@ -405,10 +417,9 @@ elf_machine_rela (struct link_map *map,
= (void *)(map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
sym_value -= map->l_addr;
sym_value -= dlsymtab[ELF64_R_SYM(reloc->r_info)].st_value;
sym_value -= reloc->r_addend;
}
else
#endif
sym_value += reloc->r_addend;
*reloc_addr = sym_value;
}
else

View File

@ -185,15 +185,11 @@ _dl_runtime_profile:
.previous
");
#endif
/* The PLT uses Elf32_Rel relocs. */
#define elf_machine_relplt elf_machine_rel
/* Mask identifying addresses reserved for the user program,
where the dynamic linker should not map anything. */
#define ELF_MACHINE_USER_ADDRESS_MASK 0xf8000000UL
/* Initial entry point code for the dynamic linker.
The C function `_dl_start' is the real entry point;
its return value is the user program's entry point. */
@ -265,7 +261,7 @@ _dl_start_user:\n\
#define elf_machine_lookup_noplt_p(type) ((type) == R_386_JMP_SLOT)
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
#define ELF_MACHINE_RELOC_NOPLT R_386_JMP_SLOT
#define ELF_MACHINE_JMP_SLOT R_386_JMP_SLOT
/* The i386 never uses Elf32_Rela relocations. */
#define ELF_MACHINE_NO_RELA 1
@ -287,6 +283,13 @@ dl_platform_init (void)
_dl_platform = NULL;
}
static inline void
elf_machine_fixup_plt (struct link_map *map, const Elf32_Rel *reloc,
Elf32_Addr *reloc_addr, Elf32_Addr value)
{
*reloc_addr = value;
}
#endif /* !dl_machine_h */
#ifdef RESOLVE

View File

@ -25,7 +25,9 @@
It has been slightly modified to compute 2^x instead of e^x, and for
single-precision.
*/
#define _GNU_SOURCE
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <float.h>
#include <ieee754.h>
#include <math.h>
@ -116,7 +118,7 @@ __ieee754_exp2f (float x)
else if (isgreaterequal (x, (float) FLT_MAX_EXP))
return huge * huge;
/* And underflow (including -inf). */
else if (isless (x, (float) (FLT_MIN_EXP - FLT_MANT_DIF)))
else if (isless (x, (float) (FLT_MIN_EXP - FLT_MANT_DIG)))
return TWOM100 * TWOM100;
/* Maybe the result needs to be a denormalised number... */
else if (!isnan (x))

View File

@ -135,8 +135,6 @@ asm (TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup) \
".set _dl_runtime_profile, _dl_runtime_resolve");
#endif
#define ELF_MACHINE_RUNTIME_FIXUP_ARGS long int save_a0, long int save_a1
/* The PLT uses Elf32_Rela relocs. */
#define elf_machine_relplt elf_machine_rela
/* Mask identifying addresses reserved for the user program,
@ -216,11 +214,18 @@ _dl_start_user:
#define elf_machine_lookup_noplt_p(type) ((type) == R_68K_JMP_SLOT)
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
#define ELF_MACHINE_RELOC_NOPLT R_68K_JMP_SLOT
#define ELF_MACHINE_JMP_SLOT R_68K_JMP_SLOT
/* The m68k never uses Elf32_Rel relocations. */
#define ELF_MACHINE_NO_REL 1
static inline void
elf_machine_fixup_plt (struct link_map *map, const Elf32_Rela *reloc,
Elf32_Addr *reloc_addr, Elf32_Addr value)
{
*reloc_addr = value + reloc->r_addend;
}
#endif /* !dl_machine_h */
#ifdef RESOLVE
@ -267,7 +272,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
break;
case R_68K_GLOB_DAT:
case R_68K_JMP_SLOT:
*reloc_addr = value;
*reloc_addr = value + reloc->r_addend;
break;
case R_68K_8:
*(char *) reloc_addr = value + reloc->r_addend;

View File

@ -197,8 +197,7 @@ _dl_runtime_resolve:
# ...unwind the stack frame, and jump to the PLT entry we updated.
addi 1,1,48
bctr
0:
.size _dl_runtime_resolve,0b-_dl_runtime_resolve
.size _dl_runtime_resolve,.-_dl_runtime_resolve
.align 2
.globl _dl_prof_resolve
@ -395,10 +394,6 @@ static ElfW(Addr) _dl_preferred_address = 1
_dl_preferred_address = mapstart; \
} )
/* We require the address of the PLT entry returned from fixup, not
the first word of the PLT entry. */
#define ELF_FIXUP_RETURN_VALUE(map, result) ((Elf32_Addr) &(result))
/* Nonzero iff TYPE should not be allowed to resolve to one of
the main executable's symbols, as for a COPY reloc. */
#define elf_machine_lookup_noexec_p(type) ((type) == R_PPC_COPY)
@ -413,7 +408,7 @@ static ElfW(Addr) _dl_preferred_address = 1
(type) == R_PPC_JMP_SLOT)
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
#define ELF_MACHINE_RELOC_NOPLT R_PPC_JMP_SLOT
#define ELF_MACHINE_JMP_SLOT R_PPC_JMP_SLOT
/* Nonzero iff TYPE describes relocation of a PLT entry, so
PLT entries should not be allowed to define the value. */
@ -554,6 +549,70 @@ elf_machine_lazy_rel (struct link_map *map, const Elf32_Rela *reloc)
/* elf_machine_runtime_setup handles this. */
}
static inline void
elf_machine_fixup_plt(struct link_map *map, const Elf32_Rela *reloc,
Elf32_Addr *reloc_addr, Elf32_Addr finaladdr)
{
Elf32_Sword delta = finaladdr - (Elf32_Word) (char *) reloc_addr;
if (delta << 6 >> 6 == delta)
*reloc_addr = OPCODE_B (delta);
else if (finaladdr <= 0x01fffffc || finaladdr >= 0xfe000000)
*reloc_addr = OPCODE_BA (finaladdr);
else
{
Elf32_Word *plt;
Elf32_Word index;
plt = (Elf32_Word *)((char *)map->l_addr
+ map->l_info[DT_PLTGOT]->d_un.d_val);
index = (reloc_addr - plt - PLT_INITIAL_ENTRY_WORDS)/2;
if (index >= PLT_DOUBLE_SIZE)
{
/* Slots greater than or equal to 2^13 have 4 words available
instead of two. */
/* FIXME: There are some possible race conditions in this code,
when called from 'fixup'.
1) Suppose that a lazy PLT entry is executing, a context switch
between threads (or a signal) occurs, and the new thread or
signal handler calls the same lazy PLT entry. Then the PLT entry
would be changed while it's being run, which will cause a segfault
(almost always).
2) Suppose the reverse: that a lazy PLT entry is being updated,
a context switch occurs, and the new code calls the lazy PLT
entry that is being updated. Then the half-fixed PLT entry will
be executed, which will also almost always cause a segfault.
These problems don't happen with the 2-word entries, because
only one of the two instructions are changed when a lazy entry
is retargeted at the actual PLT entry; the li instruction stays
the same (we have to update it anyway, because we might not be
updating a lazy PLT entry). */
reloc_addr[0] = OPCODE_LI (11, finaladdr);
reloc_addr[1] = OPCODE_ADDIS (11, 11, finaladdr + 0x8000 >> 16);
reloc_addr[2] = OPCODE_MTCTR (11);
reloc_addr[3] = OPCODE_BCTR ();
}
else
{
Elf32_Word num_plt_entries;
num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val
/ sizeof(Elf32_Rela));
plt[index+PLT_DATA_START_WORDS (num_plt_entries)] = finaladdr;
reloc_addr[0] = OPCODE_LI (11, index*4);
reloc_addr[1] = OPCODE_B (-(4*(index*2
+ 1
- PLT_LONGBRANCH_ENTRY_WORDS
+ PLT_INITIAL_ENTRY_WORDS)));
}
}
MODIFIED_CODE (reloc_addr);
}
#endif /* dl_machine_h */
#ifdef RESOLVE
@ -674,66 +733,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
}
else if (rinfo == R_PPC_JMP_SLOT)
{
Elf32_Sword delta = finaladdr - (Elf32_Word) (char *) reloc_addr;
if (delta << 6 >> 6 == delta)
*reloc_addr = OPCODE_B (delta);
else if (finaladdr <= 0x01fffffc || finaladdr >= 0xfe000000)
*reloc_addr = OPCODE_BA (finaladdr);
else
{
Elf32_Word *plt;
Elf32_Word index;
plt = (Elf32_Word *)((char *)map->l_addr
+ map->l_info[DT_PLTGOT]->d_un.d_val);
index = (reloc_addr - plt - PLT_INITIAL_ENTRY_WORDS)/2;
if (index >= PLT_DOUBLE_SIZE)
{
/* Slots greater than or equal to 2^13 have 4 words available
instead of two. */
/* FIXME: There are some possible race conditions in this code,
when called from 'fixup'.
1) Suppose that a lazy PLT entry is executing, a
context switch between threads (or a signal) occurs,
and the new thread or signal handler calls the same
lazy PLT entry. Then the PLT entry would be changed
while it's being run, which will cause a segfault
(almost always).
2) Suppose the reverse: that a lazy PLT entry is
being updated, a context switch occurs, and the new
code calls the lazy PLT entry that is being updated.
Then the half-fixed PLT entry will be executed, which
will also almost always cause a segfault.
These problems don't happen with the 2-word entries, because
only one of the two instructions are changed when a lazy
entry is retargeted at the actual PLT entry; the li
instruction stays the same (we have to update it anyway,
because we might not be updating a lazy PLT entry). */
reloc_addr[0] = OPCODE_LI (11, finaladdr);
reloc_addr[1] = OPCODE_ADDIS (11, 11, finaladdr + 0x8000 >> 16);
reloc_addr[2] = OPCODE_MTCTR (11);
reloc_addr[3] = OPCODE_BCTR ();
}
else
{
Elf32_Word num_plt_entries;
num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val
/ sizeof(Elf32_Rela));
plt[index+PLT_DATA_START_WORDS (num_plt_entries)] = finaladdr;
reloc_addr[0] = OPCODE_LI (11, index*4);
reloc_addr[1] =
OPCODE_B (-(4*(index*2
+ 1
- PLT_LONGBRANCH_ENTRY_WORDS
+ PLT_INITIAL_ENTRY_WORDS)));
}
}
MODIFIED_CODE (reloc_addr);
elf_machine_fixup_plt (map, reloc, reloc_addr, finalvalue);
}
else
{

View File

@ -126,13 +126,6 @@ _dl_runtime_resolve:
restore
.size _dl_runtime_resolve, . - _dl_runtime_resolve");
/* The address of the JMP_SLOT reloc is the .plt entry, thus we don't
dereference the reloc's addr to get the final destination. Ideally
there would be a generic way to return the value of the symbol from
elf_machine_relplt, but as it is, the address of the .plt entry is
good enough. */
#define ELF_FIXUP_RETURN_VALUE(map, result) ((Elf32_Addr) &(result))
/* Nonzero iff TYPE should not be allowed to resolve to one of
the main executable's symbols, as for a COPY reloc. */
#define elf_machine_lookup_noexec_p(type) ((type) == R_SPARC_COPY)
@ -142,7 +135,7 @@ _dl_runtime_resolve:
#define elf_machine_lookup_noplt_p(type) ((type) == R_SPARC_JMP_SLOT)
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
#define ELF_MACHINE_RELOC_NOPLT R_SPARC_JMP_SLOT
#define ELF_MACHINE_JMP_SLOT R_SPARC_JMP_SLOT
/* The SPARC never uses Elf32_Rel relocations. */
#define ELF_MACHINE_NO_REL 1
@ -150,9 +143,6 @@ _dl_runtime_resolve:
/* The SPARC overlaps DT_RELA and DT_PLTREL. */
#define ELF_MACHINE_PLTREL_OVERLAP 1
/* The PLT uses Elf32_Rela relocs. */
#define elf_machine_relplt elf_machine_rela
/* Initial entry point code for the dynamic linker.
The C function `_dl_start' is the real entry point;
its return value is the user program's entry point. */
@ -246,7 +236,30 @@ _dl_start_user:
.size _dl_start_user,.-_dl_start_user
.previous");
static inline void
elf_machine_fixup_plt (struct link_map *map, const Elf32_Rela *reloc,
Elf32_Addr *reloc_addr, Elf32_Addr value)
{
/* For thread safety, write the instructions from the bottom and
flush before we overwrite the critical "b,a". This of course
need not be done during bootstrapping, since there are no threads.
But we also can't tell if we _can_ use flush, so don't. */
reloc_addr[2] = OPCODE_JMP_G1 | (value & 0x3ff);
#ifndef RTLD_BOOTSTRAP
if (_dl_hwcap & HWCAP_SPARC_FLUSH)
__asm __volatile ("flush %0+8" : : "r"(reloc_addr));
#endif
reloc_addr[1] = OPCODE_SETHI_G1 | (value >> 10);
#ifndef RTLD_BOOTSTRAP
if (_dl_hwcap & HWCAP_SPARC_FLUSH)
__asm __volatile ("flush %0+4" : : "r"(reloc_addr));
#endif
}
#ifdef RESOLVE
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
MAP is the object containing the reloc. */
@ -305,14 +318,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
*reloc_addr = value;
break;
case R_SPARC_JMP_SLOT:
/* For thread safety, write the instructions from the bottom and
flush before we overwrite the critical "b,a". */
reloc_addr[2] = OPCODE_JMP_G1 | (value & 0x3ff);
if (_dl_hwcap & HWCAP_SPARC_FLUSH)
__asm __volatile ("flush %0+8" : : "r"(reloc_addr));
reloc_addr[1] = OPCODE_SETHI_G1 | (value >> 10);
if (_dl_hwcap & HWCAP_SPARC_FLUSH)
__asm __volatile ("flush %0+4" : : "r"(reloc_addr));
elf_machine_fixup_plt(map, reloc, reloc_addr, value);
break;
case R_SPARC_8:
*(char *) reloc_addr = value;

View File

@ -67,7 +67,26 @@ elf_machine_load_address (void)
return pc - *(Elf64_Addr *)(elf_pic_register + la);
}
static inline void
elf_machine_fixup_plt(struct link_map *map, const Elf64_Rela *reloc,
Elf64_Addr *reloc_addr, Elf64_Addr value)
{
Elf64_Dyn *pltfmt = map->l_info[DT_SPARC(PLTFMT)];
switch (pltfmt ? pltfmt->d_un.d_val : 0)
{
case 1: /* .got.plt with absolute addresses */
*reloc_addr = value;
break;
case 2: /* .got.plt with got-relative addresses */
*reloc_addr = value - (map->l_info[DT_PLTGOT]->d_un.d_ptr + map->l_addr);
break;
default:
assert (! "unexpected .plt format type");
}
}
#ifdef RESOLVE
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
MAP is the object containing the reloc. */
@ -160,21 +179,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
break;
case R_SPARC_JMP_SLOT:
{
Elf64_Dyn *pltfmt = map->l_info[DT_SPARC(PLTFMT)];
switch (pltfmt ? pltfmt->d_un.d_val : 0)
{
case 1: /* .got.plt with absolute addresses */
*reloc_addr = value;
break;
case 2: /* .got.plt with got-relative addresses */
*reloc_addr = value - (map->l_info[DT_PLTGOT]->d_un.d_ptr
+ map->l_addr);
break;
default:
assert (! "unexpected .plt format type");
}
}
elf_machine_fixup_plt(map, reloc, reloc_addr, value);
break;
case R_SPARC_NONE: /* Alright, Wilbur. */
@ -212,7 +217,7 @@ elf_machine_lazy_rel (struct link_map *map, const Elf64_Rela *reloc)
#define elf_machine_lookup_noplt_p(type) ((type) == R_SPARC_JMP_SLOT)
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
#define ELF_MACHINE_RELOC_NOPLT R_SPARC_JMP_SLOT
#define ELF_MACHINE_JMP_SLOT R_SPARC_JMP_SLOT
/* The SPARC never uses Elf64_Rel relocations. */
#define ELF_MACHINE_NO_REL 1
@ -220,13 +225,6 @@ elf_machine_lazy_rel (struct link_map *map, const Elf64_Rela *reloc)
/* The SPARC overlaps DT_RELA and DT_PLTREL. */
#define ELF_MACHINE_PLTREL_OVERLAP 1
/* The return value from dl-runtime's fixup, if it should be special. */
#define ELF_FIXUP_RETURN_VALUE(map, result) \
((map)->l_info[DT_SPARC(PLTFMT)] \
&& (map)->l_info[DT_SPARC(PLTFMT)]->d_un.d_val == 2 \
? (result) + (map)->l_info[DT_PLTGOT]->d_un.d_ptr + (map)->l_addr \
: (result))
/* Set up the loaded object described by L so its unrelocated PLT
entries will jump to the on-demand fixup code in dl-runtime.c. */

View File

@ -1,5 +1,5 @@
/* Machine-dependent ELF dynamic relocation inline functions. Stub version.
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Copyright (C) 1995, 1996, 1997 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
@ -51,9 +51,14 @@ elf_machine_load_address (void)
#error "Where am I?"
}
/* This can modify DYNAMIC_INFO to avoid relocating code in
the functions above if they are doing bizarre magic. */
#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) /* nothing */
/* Fixup a PLT entry to bounce directly to the function at VALUE. */
static inline void
elf_machine_fixup_plt (struct link_map *map, const Elf32_Rel *reloc,
Elf32_Addr *reloc_addr, Elf32_Addr value)
{
*reloc_addr = value;
}
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
LOADADDR is the load address of the object; INFO is an array indexed
@ -82,7 +87,7 @@ elf_machine_rel (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
}
static inline void
static inline Elf32_Addr
elf_machine_rela (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
const Elf32_Rel *reloc, const Elf32_Sym *sym,
Elf32_Addr (*resolve) (const Elf32_Sym **ref,

View File

@ -32,6 +32,7 @@ nfsservctl EXTRA nfsservctl 3 nfsservctl
pause - pause 0 __libc_pause pause
personality init-first personality 1 __personality personality
pipe - pipe 1 __pipe pipe
prctl EXTRA prctl 5
query_module EXTRA query_module 5 query_module
quotactl EXTRA quotactl 4 quotactl
s_getdents EXTRA getdents 3 __getdents