diff options
41 files changed, 1427 insertions, 702 deletions
@@ -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. @@ -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?'' @@ -687,6 +690,14 @@ 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: {UD} Ulrich Drepper, <drepper@cygnus.com> @@ -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. diff --git a/config.make.in b/config.make.in index ba689ec..ae4d898 100644 --- a/config.make.in +++ b/config.make.in @@ -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. @@ -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 diff --git a/configure.in b/configure.in index 4c507bb..efa338c 100644 --- a/configure.in +++ b/configure.in @@ -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 diff --git a/elf/Makefile b/elf/Makefile index fb85b85..5f78c5c 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -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. diff --git a/elf/dl-addr.c b/elf/dl-addr.c new file mode 100644 index 0000000..d50cc4b --- /dev/null +++ b/elf/dl-addr.c @@ -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; +} diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c index e7132ed..3f09d72 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -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 -# define PLTREL ElfW(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); - { - 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" + /* Sanity check that we're really looking at a PLT relocation. */ + assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT); - /* Perform the specified relocation. */ - if (l->l_info[VERSYMIDX (DT_VERSYM)]) + /* Look up the target symbol. */ + switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL) + { + 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)]; - - here_version = &l->l_versions[ndx]; + 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]; + + if (version->hash != 0) + { + value = _dl_lookup_versioned_symbol(strtab + sym->st_name, + &sym, scope, l->l_name, + version, ELF_MACHINE_JMP_SLOT); + break; + } } - else - here_version = NULL; + case 0: + value = _dl_lookup_symbol (strtab + sym->st_name, &sym, scope, + l->l_name, ELF_MACHINE_JMP_SLOT); + } + + /* 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 - elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)], - here_version, (void *) rel_addr); - } + /* 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); - { - const struct r_found_version *here_version; + /* Sanity check that we're really looking at a PLT relocation. */ + assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT); - /* 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)]) + /* Look up the target symbol. */ + switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL) + { + 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)]; - - here_version = &l->l_versions[ndx]; + 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]; + + if (version->hash != 0) + { + value = _dl_lookup_versioned_symbol(strtab + sym->st_name, + &sym, scope, l->l_name, + version, ELF_MACHINE_JMP_SLOT); + break; + } } - else - here_version = NULL; + case 0: + value = _dl_lookup_symbol (strtab + sym->st_name, &sym, scope, + l->l_name, ELF_MACHINE_JMP_SLOT); + } + + /* 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); - elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)], - here_version, (void *) &result); - } + /* 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 diff --git a/elf/dladdr.c b/elf/dladdr.c index 59e9783..d82a9e7 100644 --- a/elf/dladdr.c +++ b/elf/dladdr.c @@ -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); } diff --git a/elf/dlfcn.h b/elf/dlfcn.h index 9db5fb4..825b484 100644 --- a/elf/dlfcn.h +++ b/elf/dlfcn.h @@ -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 @@ -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); @@ -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); diff --git a/libio/libio.h b/libio/libio.h index 9e8c108..1dddaf2 100644 --- a/libio/libio.h +++ b/libio/libio.h @@ -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 -# include <bits/stdio-lock.h> +# 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)); diff --git a/libio/libioP.h b/libio/libioP.h index 66acb93..2337071 100644 --- a/libio/libioP.h +++ b/libio/libioP.h @@ -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" diff --git a/locale/C_name.c b/locale/C_name.c index 5e7cb85..fa2ac05 100644 --- a/locale/C_name.c +++ b/locale/C_name.c @@ -5,3 +5,4 @@ /* Name of our standard locale. */ const char _nl_C_name[] = "C"; +const char _nl_POSIX_name[] = "POSIX"; diff --git a/locale/findlocale.c b/locale/findlocale.c index 308aa2b..c027968 100644 --- a/locale/findlocale.c +++ b/locale/findlocale.c @@ -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) { diff --git a/locale/localeinfo.h b/locale/localeinfo.h index 79db06d..29731fa 100644 --- a/locale/localeinfo.h +++ b/locale/localeinfo.h @@ -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) \ diff --git a/locale/setlocale.c b/locale/setlocale.c index 79f15cc..42c1e50 100644 --- a/locale/setlocale.c +++ b/locale/setlocale.c @@ -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; } diff --git a/malloc/Makefile b/malloc/Makefile index b43ce13..addabf1 100644 --- a/malloc/Makefile +++ b/malloc/Makefile @@ -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 $@ diff --git a/malloc/malloc.c b/malloc/malloc.c index fb51483..17350eb 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -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; diff --git a/malloc/malloc.h b/malloc/malloc.h index a72102e..6538170 100644 --- a/malloc/malloc.h +++ b/malloc/malloc.h @@ -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 diff --git a/malloc/mcheck.c b/malloc/mcheck.c index 1a80a56..47d35f1 100644 --- a/malloc/mcheck.c +++ b/malloc/mcheck.c @@ -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,19 +107,27 @@ freehook (ptr) ptr = (__ptr_t) hdr; } __free_hook = old_free_hook; - free (ptr); + 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; - hdr = (struct hdr *) malloc (sizeof (struct hdr) + size + 1); + 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) return 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; diff --git a/malloc/mtrace.awk b/malloc/mtrace.awk deleted file mode 100644 index 06844d1..0000000 --- a/malloc/mtrace.awk +++ /dev/null @@ -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]; -} diff --git a/malloc/mtrace.c b/malloc/mtrace.c index 3f0cbb9..aeefd56 100644 --- a/malloc/mtrace.c +++ b/malloc/mtrace.c @@ -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; - free (ptr); + 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; - hdr = (__ptr_t) malloc (size); + 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,21 +168,24 @@ tr_reallochook (ptr, size) __free_hook = tr_old_free_hook; __malloc_hook = tr_old_malloc_hook; __realloc_hook = tr_old_realloc_hook; - hdr = (__ptr_t) realloc (ptr, size); + 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; __realloc_hook = tr_reallochook; __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 (); diff --git a/malloc/mtrace.pl b/malloc/mtrace.pl new file mode 100644 index 0000000..46d8425 --- /dev/null +++ b/malloc/mtrace.pl @@ -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; diff --git a/manual/time.texi b/manual/time.texi index d711234..7a5cd65 100644 --- a/manual/time.texi +++ b/manual/time.texi @@ -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 _ diff --git a/math/atest-exp2.c b/math/atest-exp2.c index 95e72aa..1f5d7cc 100644 --- a/math/atest-exp2.c +++ b/math/atest-exp2.c @@ -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> @@ -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ôte no_program [ no_version ]\n" 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ègles de \"%s\", ligne %d)" 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évue: %s.\n" 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ée.\n" 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'écriture de %s.\n" 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ë.\n" 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ée par expiration du délai d'inactivité." 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ème interrompu, il aurait dû être relancé." 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é du client invalide." 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 "Échange invalide." 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 "Échec d'allocation de ressources locales." 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ée disponible." 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ésiré." 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ésultat numérique est en dehors de l'intervalle." 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ée." 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é dans le code n'est pas chargé dynamiquement." 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êt lors de trace." 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éjà connecté." 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ème inconnue." 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éfini de données." 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ésultat anarchique résultant de l'exécution de la commande." 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étaire du fichier .rhosts." 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égorie `%s'." 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é de clé." 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é avec un mauvais bloc ttisstd." 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émoire écrasée après la fin du bloc alloué." #: 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 été enregistré.\n" 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éfinition de type `UNDEFINED'." 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: écriture (configuration de stderr): %m.\n" 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ère définition." # 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ères." 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éfinies?!" 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ème à répondre au programme %d.\n" 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'écriture dans le fichier de la base de données." 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" diff --git a/string/Makefile b/string/Makefile index b0200e5..1a1b269 100644 --- a/string/Makefile +++ b/string/Makefile @@ -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 diff --git a/string/bits/string2.h b/string/bits/string2.h index 51255aa..8555d67 100644 --- a/string/bits/string2.h +++ b/string/bits/string2.h @@ -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: \ diff --git a/string/tester.c b/string/tester.c index ee36e12..5b7b2f9 100644 --- a/string/tester.c +++ b/string/tester.c @@ -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,40 +966,123 @@ 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); - } +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. */ - { - 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); - } + test_strerror (); - { - int status; - if (errors == 0) - { - status = EXIT_SUCCESS; - puts("No errors."); - } - else - { - status = EXIT_FAILURE; - printf("%Zd errors.\n", errors); - } - exit(status); - } + + if (errors == 0) + { + status = EXIT_SUCCESS; + puts("No errors."); + } + else + { + status = EXIT_FAILURE; + printf("%Zd errors.\n", errors); + } + exit(status); } diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h index e0ba67b..d3eb242 100644 --- a/sysdeps/alpha/dl-machine.h +++ b/sysdeps/alpha/dl-machine.h @@ -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. */ - *(Elf64_Addr *)(plt + 16) = (Elf64_Addr) &_dl_runtime_resolve; + 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 diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h index 041643e..0ac67c0 100644 --- a/sysdeps/i386/dl-machine.h +++ b/sysdeps/i386/dl-machine.h @@ -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 diff --git a/sysdeps/libm-ieee754/s_exp2f.c b/sysdeps/libm-ieee754/s_exp2f.c index e50ac77..92c1f16 100644 --- a/sysdeps/libm-ieee754/s_exp2f.c +++ b/sysdeps/libm-ieee754/s_exp2f.c @@ -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)) diff --git a/sysdeps/m68k/dl-machine.h b/sysdeps/m68k/dl-machine.h index 44eefb2..cc0fb56 100644 --- a/sysdeps/m68k/dl-machine.h +++ b/sysdeps/m68k/dl-machine.h @@ -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; diff --git a/sysdeps/powerpc/dl-machine.h b/sysdeps/powerpc/dl-machine.h index 70a3f20..beabc1d 100644 --- a/sysdeps/powerpc/dl-machine.h +++ b/sysdeps/powerpc/dl-machine.h @@ -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 { diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h index b80c126..288a140 100644 --- a/sysdeps/sparc/sparc32/dl-machine.h +++ b/sysdeps/sparc/sparc32/dl-machine.h @@ -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; diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h index e302f4a..2266231 100644 --- a/sysdeps/sparc/sparc64/dl-machine.h +++ b/sysdeps/sparc/sparc64/dl-machine.h @@ -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. */ diff --git a/sysdeps/stub/dl-machine.h b/sysdeps/stub/dl-machine.h index 239d0b0..f787df3 100644 --- a/sysdeps/stub/dl-machine.h +++ b/sysdeps/stub/dl-machine.h @@ -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, @@ -107,7 +112,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy) { extern void _dl_runtime_resolve (Elf32_Word); - if (lazy) + if (lazy) { /* The GOT entries for functions in the PLT have not yet been filled in. Their initial contents will arrange when called to push an diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list index a3b0eef..d5c486d 100644 --- a/sysdeps/unix/sysv/linux/syscalls.list +++ b/sysdeps/unix/sysv/linux/syscalls.list @@ -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 |